@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,114 @@
1
+ import { statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import type { ProjectModuleLoader } from './project-tools';
4
+
5
+ /**
6
+ * Makes a live editor session see dependencies installed UNDER it.
7
+ *
8
+ * The problem, measured: `vgai add mesh` copies `src/lib/mesh/**` in and runs
9
+ * `npm install three-bvh-csg …`, but a session that is already running keeps
10
+ * failing every Node module-lane call with
11
+ * `Cannot find module 'three-bvh-csg' imported from …/src/lib/mesh/modifiers.ts`
12
+ * — while `require.resolve` from the very same project directory succeeds.
13
+ *
14
+ * The mechanism is a cached FAILURE, not a cached resolution. Vite's SSR
15
+ * module runner memoises a module's load promise on its module-graph node and
16
+ * never clears it when that promise REJECTS
17
+ * (`vite/dist/node/module-runner.js`, `cachedRequest`: `mod.promise = promise`
18
+ * inside a `try`/`finally` that only flips `evaluated`). So the first load of
19
+ * `modifiers.ts` attempted before the package existed poisons that module for
20
+ * the life of the process, and every later call replays the identical
21
+ * rejection — including calls from brand-new files that merely import it. The
22
+ * poison is per-module, not per-package: a fresh module importing
23
+ * `three-bvh-csg` DIRECTLY resolves it fine at the same moment.
24
+ *
25
+ * That also explains the two things the symptom report noted. Editing the
26
+ * importing file "fixes" it, because an HMR invalidation drops the module
27
+ * node together with its rejected promise. And `vgai restart` does not, because
28
+ * it re-issues `play` to the browser and never touches this Node process.
29
+ *
30
+ * The fix is to perform that same invalidation when the project's dependency
31
+ * set moves. This is checked ON USE rather than from a file watcher on
32
+ * purpose: `vgai add` installs and returns, and the next thing a caller does
33
+ * is run the tool. A debounced watcher races that window; a fingerprint read
34
+ * at load time cannot.
35
+ */
36
+
37
+ /**
38
+ * Files whose contents define which packages a project has. `package.json`
39
+ * alone is not enough — a bare `npm install` that only writes the lockfile
40
+ * still changes what is resolvable — and the lockfile alone is not enough
41
+ * either, since `vgai add` merges dependencies into `package.json` first.
42
+ */
43
+ export const DEPENDENCY_MANIFEST_FILES = [
44
+ 'package.json',
45
+ 'package-lock.json',
46
+ 'npm-shrinkwrap.json',
47
+ 'pnpm-lock.yaml',
48
+ 'yarn.lock',
49
+ 'bun.lock',
50
+ 'bun.lockb',
51
+ ] as const;
52
+
53
+ /**
54
+ * Cheap stat-based fingerprint of a project's dependency manifests. Size is
55
+ * carried alongside mtime because an install that lands inside one filesystem
56
+ * timestamp tick still changes the file's length.
57
+ */
58
+ export function dependencyManifestFingerprint(projectRoot: string): string {
59
+ return DEPENDENCY_MANIFEST_FILES.map((name) => {
60
+ try {
61
+ const stats = statSync(join(projectRoot, name));
62
+ return `${name}:${stats.mtimeMs}:${stats.size}`;
63
+ } catch {
64
+ return `${name}:-`;
65
+ }
66
+ }).join('|');
67
+ }
68
+
69
+ export interface DependencyChangeInvalidationDeps {
70
+ /** Read live — the open project changes at runtime. */
71
+ getProjectRoot: () => string;
72
+ /**
73
+ * Drop everything the Node module lane has cached for this project. The
74
+ * owning dev server implements it as
75
+ * `vite.environments.ssr.moduleGraph.invalidateAll()`; a host without a
76
+ * bundler (the static production server) has nothing to invalidate and
77
+ * omits it, leaving the loader a plain pass-through.
78
+ */
79
+ invalidateModules?: (() => void) | undefined;
80
+ }
81
+
82
+ /**
83
+ * Wraps a project-module loader so a dependency change invalidates the cached
84
+ * module graph before the next load. Returns `undefined` for an absent loader
85
+ * so hosts that never load project modules stay unchanged.
86
+ */
87
+ export function withDependencyChangeInvalidation(
88
+ load: ProjectModuleLoader | undefined,
89
+ deps: DependencyChangeInvalidationDeps,
90
+ ): ProjectModuleLoader | undefined {
91
+ if (!load) return undefined;
92
+ const { getProjectRoot, invalidateModules } = deps;
93
+ if (!invalidateModules) return load;
94
+
95
+ let lastProjectRoot: string | null = null;
96
+ let lastFingerprint: string | null = null;
97
+
98
+ return async (absoluteModuleId: string): Promise<unknown> => {
99
+ const projectRoot = getProjectRoot();
100
+ const fingerprint = dependencyManifestFingerprint(projectRoot);
101
+ // A different project is a fresh baseline, never an invalidation: opening
102
+ // a project already rebuilds what the graph holds for it.
103
+ if (
104
+ lastProjectRoot === projectRoot &&
105
+ lastFingerprint !== null &&
106
+ lastFingerprint !== fingerprint
107
+ ) {
108
+ invalidateModules();
109
+ }
110
+ lastProjectRoot = projectRoot;
111
+ lastFingerprint = fingerprint;
112
+ return load(absoluteModuleId);
113
+ };
114
+ }
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Reading a project's files as FACTS: install its dependencies, hash a tree,
3
+ * snapshot it for collaboration, and name a file's content type.
4
+ *
5
+ * None of this holds session state — every function takes the paths it works
6
+ * on. The collaboration snapshot in particular is a pure read: it is what a
7
+ * joining participant is told the project currently contains.
8
+ */
9
+
10
+ import { spawn } from 'node:child_process';
11
+ import { createHash } from 'node:crypto';
12
+ import { type Dirent, readFileSync } from 'node:fs';
13
+ import { readdir, readFile, stat, unlink } from 'node:fs/promises';
14
+ import type { IncomingMessage } from 'node:http';
15
+ import { join, relative, sep } from 'node:path';
16
+ import { isContainedRelativePath } from '@volter/editor-sdk/session/relative-path-guard';
17
+
18
+ export async function installProjectDependencies(projectPath: string): Promise<void> {
19
+ await new Promise<void>((resolveInstall, rejectInstall) => {
20
+ const child = spawn(
21
+ 'npm',
22
+ ['install', '--prefer-offline', '--no-audit', '--no-fund', '--loglevel=error'],
23
+ {
24
+ cwd: projectPath,
25
+ stdio: 'ignore',
26
+ shell: true,
27
+ },
28
+ );
29
+ child.once('error', rejectInstall);
30
+ child.once('close', (code) => {
31
+ if (code === 0) resolveInstall();
32
+ else rejectInstall(new Error(`npm install exited with code ${code ?? 'unknown'}`));
33
+ });
34
+ });
35
+ }
36
+
37
+ export function readRunningEngineVersion(engineRoot: string): string | null {
38
+ const candidates = [
39
+ join(engineRoot, 'packages', 'editor-core', 'package.json'),
40
+ join(engineRoot, 'node_modules', '@volter', 'editor-core', 'package.json'),
41
+ ];
42
+ for (const path of candidates) {
43
+ try {
44
+ const parsed = JSON.parse(readFileSync(path, 'utf-8')) as { version?: unknown };
45
+ if (typeof parsed.version === 'string') return parsed.version;
46
+ } catch {
47
+ // Try the next supported checkout/installed-package layout.
48
+ }
49
+ }
50
+ // Packaged mode passes the installed `@vgai/editor` package as engineRoot.
51
+ // npm/pnpm may hoist its runtime-package dependencies to the PROJECT's
52
+ // node_modules, outside both candidates above; reading that project copy
53
+ // would merely echo the manifest pin and make every mismatch look healthy.
54
+ // Release-train package versions are synchronized, so the installed
55
+ // editor's own version is the authoritative identity in this layout. Keep
56
+ // the name check strict: the monorepo root has its own unrelated package
57
+ // version and must never masquerade as the engine version.
58
+ try {
59
+ const parsed = JSON.parse(readFileSync(join(engineRoot, 'package.json'), 'utf-8')) as {
60
+ name?: unknown;
61
+ version?: unknown;
62
+ };
63
+ if (parsed.name === '@volter/editor-core' && typeof parsed.version === 'string') {
64
+ return parsed.version;
65
+ }
66
+ } catch {
67
+ // No packaged-editor identity at this root.
68
+ }
69
+ return null;
70
+ }
71
+
72
+ // ---------------------------------------------------------------------------
73
+ // File hashing — partial hash for large files (first 64KB + size)
74
+ // ---------------------------------------------------------------------------
75
+
76
+ const PARTIAL_HASH_THRESHOLD = 10 * 1024 * 1024; // 10MB
77
+
78
+ export async function hashAndSize(absPath: string): Promise<{ hash: string; size: number }> {
79
+ const data = await readFile(absPath);
80
+ const hash = createHash('sha256');
81
+ if (data.length > PARTIAL_HASH_THRESHOLD) {
82
+ hash.update(data.subarray(0, 65536));
83
+ hash.update(`\0size:${data.length}`);
84
+ } else {
85
+ hash.update(data);
86
+ }
87
+ return { hash: hash.digest('hex').slice(0, 16), size: data.length };
88
+ }
89
+
90
+ export async function unlinkIfPresent(path: string): Promise<void> {
91
+ try {
92
+ await unlink(path);
93
+ } catch (error) {
94
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
95
+ }
96
+ }
97
+
98
+ export async function scanDirForHashes(
99
+ dir: string,
100
+ hashCache: Map<string, string>,
101
+ sizeCache: Map<string, number>,
102
+ ): Promise<void> {
103
+ let entries: Dirent[];
104
+ try {
105
+ entries = await readdir(dir, { withFileTypes: true });
106
+ } catch {
107
+ return;
108
+ }
109
+ for (const entry of entries) {
110
+ if (entry.name.startsWith('.')) continue;
111
+ const full = join(dir, entry.name);
112
+ if (entry.isDirectory()) {
113
+ await scanDirForHashes(full, hashCache, sizeCache);
114
+ } else if (entry.isFile()) {
115
+ try {
116
+ const { hash, size } = await hashAndSize(full);
117
+ hashCache.set(full, hash);
118
+ sizeCache.set(full, size);
119
+ } catch {
120
+ /* skip unreadable files */
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ const COLLABORATION_IGNORED_DIRS = new Set([
127
+ 'node_modules',
128
+ 'dist',
129
+ 'coverage',
130
+ 'logs',
131
+ '.git',
132
+ '.vgai',
133
+ ]);
134
+
135
+ /** The project-owned estate: every file under the project root except the
136
+ * installed, generated and private directories above, and every dotfile.
137
+ * The same set `collaborationSourceSnapshot` publishes to a joining
138
+ * participant — one line, not a second weaker one. */
139
+ export function isProjectOwnedRelativePath(path: string): boolean {
140
+ if (!isContainedRelativePath(path)) return false;
141
+ return !path
142
+ .split('/')
143
+ .some((segment) => segment.startsWith('.') || COLLABORATION_IGNORED_DIRS.has(segment));
144
+ }
145
+
146
+ /** The project's own files with size and mtime — a listing, not a read, so
147
+ * asking what is there does not cost what is in it. */
148
+ export async function projectFileIndex(
149
+ projectRoot: string,
150
+ ): Promise<Array<{ path: string; size: number; mtime: number }>> {
151
+ const files: Array<{ path: string; size: number; mtime: number }> = [];
152
+ const visit = async (dir: string): Promise<void> => {
153
+ let entries: Dirent[];
154
+ try {
155
+ entries = await readdir(dir, { withFileTypes: true });
156
+ } catch {
157
+ return;
158
+ }
159
+ for (const entry of entries) {
160
+ if (entry.name.startsWith('.') || COLLABORATION_IGNORED_DIRS.has(entry.name)) continue;
161
+ const full = join(dir, entry.name);
162
+ if (entry.isDirectory()) {
163
+ await visit(full);
164
+ continue;
165
+ }
166
+ if (!entry.isFile()) continue;
167
+ try {
168
+ const info = await stat(full);
169
+ files.push({
170
+ path: relative(projectRoot, full).split(sep).join('/'),
171
+ size: info.size,
172
+ mtime: info.mtimeMs,
173
+ });
174
+ } catch {
175
+ /* vanished between readdir and stat: it is not in the project now */
176
+ }
177
+ }
178
+ };
179
+ await visit(projectRoot);
180
+ return files.sort((left, right) => left.path.localeCompare(right.path));
181
+ }
182
+
183
+ export async function collaborationSourceSnapshot(
184
+ projectRoot: string,
185
+ ): Promise<Array<{ path: string; sha: string }>> {
186
+ const resources: Array<{ path: string; sha: string }> = [];
187
+ const visit = async (dir: string): Promise<void> => {
188
+ let entries: Dirent[];
189
+ try {
190
+ entries = await readdir(dir, { withFileTypes: true });
191
+ } catch {
192
+ return;
193
+ }
194
+ for (const entry of entries) {
195
+ if (entry.name.startsWith('.') || COLLABORATION_IGNORED_DIRS.has(entry.name)) continue;
196
+ const full = join(dir, entry.name);
197
+ if (entry.isDirectory()) {
198
+ await visit(full);
199
+ continue;
200
+ }
201
+ if (!entry.isFile()) continue;
202
+ const { hash } = await hashAndSize(full);
203
+ resources.push({
204
+ path: relative(projectRoot, full).split(sep).join('/'),
205
+ sha: hash,
206
+ });
207
+ }
208
+ };
209
+ await visit(projectRoot);
210
+ return resources.sort((left, right) => left.path.localeCompare(right.path));
211
+ }
212
+
213
+ // ---------------------------------------------------------------------------
214
+ // MIME type detection
215
+ export const mimeTypes: Record<string, string> = {
216
+ json: 'application/json',
217
+ glb: 'model/gltf-binary',
218
+ gltf: 'model/gltf+json',
219
+ png: 'image/png',
220
+ jpg: 'image/jpeg',
221
+ jpeg: 'image/jpeg',
222
+ webp: 'image/webp',
223
+ svg: 'image/svg+xml',
224
+ wav: 'audio/wav',
225
+ mp3: 'audio/mpeg',
226
+ ogg: 'audio/ogg',
227
+ gif: 'image/gif',
228
+ };
229
+
230
+ /** One raw request header as a single string (Node hands back `string[]` for
231
+ * the repeatable ones). The share-claim headers are all single-valued. */
232
+ export function headerValue(request: IncomingMessage, name: string): string | undefined {
233
+ const value = request.headers[name.toLowerCase()];
234
+ return Array.isArray(value) ? value[0] : value;
235
+ }
@@ -0,0 +1,215 @@
1
+ import path from 'node:path';
2
+ import { isEditorLanePath } from '@volter/editor-sdk/session/tool-contribution-convention';
3
+ import ts from 'typescript';
4
+ import type { ImportersOf } from './project-root-surface';
5
+ import { resolveOidSurface } from './project-root-surface';
6
+
7
+ export type ProjectHotUpdateKind =
8
+ | 'outside'
9
+ | 'stock-data'
10
+ | 'react'
11
+ | 'r3f-refresh'
12
+ | 'r3f-entry'
13
+ | 'tool'
14
+ | 'restart'
15
+ | 'ignore';
16
+
17
+ /** Only locally proven component exports earn stock Fast Refresh. A wrong
18
+ * positive can reload the whole editor. Parse all declarations (including
19
+ * inline/indented exports), and never infer a component from an uppercase
20
+ * value, an arbitrary factory call, or an uninspected re-export.
21
+ */
22
+ export function reactRefreshBoundaryExports(source: string): readonly string[] | null {
23
+ const file = ts.createSourceFile(
24
+ 'boundary.tsx',
25
+ source,
26
+ ts.ScriptTarget.Latest,
27
+ true,
28
+ ts.ScriptKind.TSX,
29
+ );
30
+ const bindings = new Map<string, ts.Node>();
31
+ const reactWrappers = new Set<string>();
32
+ const reactNamespaces = new Set<string>();
33
+ for (const statement of file.statements) {
34
+ if (ts.isFunctionDeclaration(statement) && statement.name)
35
+ bindings.set(statement.name.text, statement);
36
+ if (ts.isVariableStatement(statement)) {
37
+ for (const declaration of statement.declarationList.declarations) {
38
+ if (ts.isIdentifier(declaration.name) && declaration.initializer)
39
+ bindings.set(declaration.name.text, declaration.initializer);
40
+ }
41
+ }
42
+ if (
43
+ ts.isImportDeclaration(statement) &&
44
+ ts.isStringLiteral(statement.moduleSpecifier) &&
45
+ statement.moduleSpecifier.text === 'react'
46
+ ) {
47
+ const clause = statement.importClause;
48
+ if (clause?.name) reactNamespaces.add(clause.name.text);
49
+ if (clause?.namedBindings && ts.isNamespaceImport(clause.namedBindings))
50
+ reactNamespaces.add(clause.namedBindings.name.text);
51
+ if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
52
+ for (const binding of clause.namedBindings.elements) {
53
+ if (['memo', 'forwardRef'].includes((binding.propertyName ?? binding.name).text))
54
+ reactWrappers.add(binding.name.text);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ const component = (node: ts.Node, seen = new Set<string>()): boolean => {
60
+ if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node))
61
+ return !node.name || /^[A-Z]/.test(node.name.text);
62
+ if (ts.isArrowFunction(node)) return true;
63
+ if (
64
+ ts.isParenthesizedExpression(node) ||
65
+ ts.isAsExpression(node) ||
66
+ ts.isSatisfiesExpression(node)
67
+ )
68
+ return component(node.expression, seen);
69
+ if (ts.isIdentifier(node)) {
70
+ if (seen.has(node.text) || !/^[A-Z]/.test(node.text)) return false;
71
+ const binding = bindings.get(node.text);
72
+ seen.add(node.text);
73
+ return binding !== undefined && component(binding, seen);
74
+ }
75
+ if (ts.isCallExpression(node)) {
76
+ const callee = node.expression;
77
+ const wrapper = ts.isIdentifier(callee)
78
+ ? reactWrappers.has(callee.text)
79
+ : ts.isPropertyAccessExpression(callee) &&
80
+ ts.isIdentifier(callee.expression) &&
81
+ reactNamespaces.has(callee.expression.text) &&
82
+ ['memo', 'forwardRef'].includes(callee.name.text);
83
+ return wrapper && node.arguments[0] !== undefined && component(node.arguments[0], seen);
84
+ }
85
+ return false;
86
+ };
87
+ const exports: string[] = [];
88
+ for (const statement of file.statements) {
89
+ if (ts.isExportAssignment(statement)) {
90
+ if (
91
+ statement.isExportEquals ||
92
+ ts.isArrowFunction(statement.expression) ||
93
+ !component(statement.expression)
94
+ )
95
+ return null;
96
+ exports.push('default');
97
+ continue;
98
+ }
99
+ if (ts.isExportDeclaration(statement)) {
100
+ if (statement.isTypeOnly) continue;
101
+ if (
102
+ statement.moduleSpecifier ||
103
+ !statement.exportClause ||
104
+ !ts.isNamedExports(statement.exportClause)
105
+ )
106
+ return null;
107
+ for (const spec of statement.exportClause.elements) {
108
+ if (spec.isTypeOnly) continue;
109
+ if (spec.name.text !== 'default' && !/^[A-Z]/.test(spec.name.text)) return null;
110
+ if (!component(spec.propertyName ?? spec.name)) return null;
111
+ exports.push(spec.name.text);
112
+ }
113
+ continue;
114
+ }
115
+ const modifiers = ts.canHaveModifiers(statement) ? ts.getModifiers(statement) : undefined;
116
+ if (!modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) continue;
117
+ if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) continue;
118
+ if (ts.isFunctionDeclaration(statement)) {
119
+ if (!statement.name || !/^[A-Z]/.test(statement.name.text)) return null;
120
+ exports.push(
121
+ modifiers.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)
122
+ ? 'default'
123
+ : statement.name.text,
124
+ );
125
+ } else if (ts.isVariableStatement(statement)) {
126
+ for (const declaration of statement.declarationList.declarations) {
127
+ if (
128
+ !ts.isIdentifier(declaration.name) ||
129
+ !/^[A-Z]/.test(declaration.name.text) ||
130
+ !declaration.initializer ||
131
+ !component(declaration.initializer)
132
+ )
133
+ return null;
134
+ exports.push(declaration.name.text);
135
+ }
136
+ } else return null;
137
+ }
138
+ return exports.length ? exports.sort() : null;
139
+ }
140
+
141
+ export function isReactRefreshBoundary(source: string): boolean {
142
+ return reactRefreshBoundaryExports(source) !== null;
143
+ }
144
+
145
+ /**
146
+ * Classify a Vite watcher update for the editor's project-script HMR seam.
147
+ *
148
+ * Only modules below the project's `src/` directory are game code. Build
149
+ * output, tests, one-off scripts, and dependency caches may also contain
150
+ * JavaScript, but importing them into the live game is both surprising and
151
+ * unsafe (a project build used to make the editor import `dist/assets/*`).
152
+ */
153
+ export function classifyProjectHotUpdate(
154
+ file: string,
155
+ projectRoot: string,
156
+ source = '',
157
+ importersOf?: ImportersOf,
158
+ ): ProjectHotUpdateKind {
159
+ const normalizedFile = file.replaceAll('\\', '/');
160
+ const normalizedRoot = projectRoot.replaceAll('\\', '/').replace(/\/$/, '');
161
+ const relative = path.posix.relative(normalizedRoot, normalizedFile);
162
+
163
+ if (relative === '' || relative === '..' || relative.startsWith('../')) {
164
+ // A repo-vendored game's source (`vendor/games/<id>/…`) is the OPEN
165
+ // GAME's own code even though it lives outside the project folder — the
166
+ // project's ingest root maps to it. Classifying it `outside` handed it to
167
+ // STOCK Vite HMR, whose unbounded propagation re-stamped ~33 editor
168
+ // modules per creation-site write (the write route writes these files),
169
+ // fanned an HMR update at the tab, and split editor singletons
170
+ // (`play-mode.ts`'s game container) so every ▶ after a write refused —
171
+ // measured on bubbo-bubbo, 2026-08-21. `restart` is the honest kind: the
172
+ // ingest world re-derives from source on its next mount, and the
173
+ // swallowed-HMR path stamps the module graph with the editor-chrome
174
+ // boundary instead of letting stock HMR walk into the editor.
175
+ if (normalizedFile.includes('/vendor/games/') && /\.(ts|tsx|js|jsx)$/.test(normalizedFile)) {
176
+ return 'restart';
177
+ }
178
+ return 'outside';
179
+ }
180
+ if (relative === 'vgai.project.json') return 'restart';
181
+ if (!relative.startsWith('src/')) return 'ignore';
182
+ if (/\.data\.json$/.test(relative)) return 'stock-data';
183
+ if (!/\.(ts|tsx|js|jsx)$/.test(relative)) return 'ignore';
184
+ // Project-tool definitions, surfaces, documents, and their local helpers
185
+ // are editor tooling. They remount through the tool contribution store's
186
+ // own cache-busted import, never through game restart or React Refresh.
187
+ if (isEditorLanePath(relative)) return 'tool';
188
+ // R3F is a React renderer: a component-only module can refresh without
189
+ // replacing its scene. Mixed component/data exports still need the editor's
190
+ // remount boundary, because React Refresh cannot safely accept them.
191
+ //
192
+ // `resolveOidSurface` — the SAME single decision `vite-plugin-ui-oid.ts`'s
193
+ // OID-stamping transform stamps with, not a separate copy kept in lockstep
194
+ // by hand. It decides from the manifest when this exact file is a root's
195
+ // `entry`, from the live import graph when it's reachable from exactly one
196
+ // root's `entry` (`importersOf`, when the caller has one — see
197
+ // `dev.ts`/`packaged.ts`'s `handleHotUpdate`), and otherwise from the file's
198
+ // own dialect evidence (a direct `@react-three/fiber` /
199
+ // `@vgai/game-runtime/world3d-react` import, OR an R3F-only intrinsic tag like
200
+ // `<mesh>`). Reading its ATTRIBUTE rather than its surface is what keeps the
201
+ // two halves identical by construction: a file stamped `userData-oid` is, by
202
+ // definition, an R3F module. Its export shape decides whether the renderer
203
+ // can refresh or needs the design-session remount.
204
+ if (/\.(tsx|jsx)$/.test(relative)) {
205
+ if (resolveOidSurface(file, source, importersOf).attribute === 'userData-oid')
206
+ return isReactRefreshBoundary(source) ? 'r3f-refresh' : 'r3f-entry';
207
+ // Stock Fast Refresh ONLY when the module provably is a Fast Refresh
208
+ // boundary. Anything else the editor owns (swallow + stamp the module
209
+ // graph + `vgai:restart-required`), because letting Vite propagate a
210
+ // project module that is not a boundary full-reloads the editor page and
211
+ // silently destroys the running game — see `isReactRefreshBoundary`.
212
+ return isReactRefreshBoundary(source) ? 'react' : 'restart';
213
+ }
214
+ return 'restart';
215
+ }