@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,430 @@
1
+ /**
2
+ * The headless Blender build, served to the editor tab — and the door that
3
+ * says WHICH BUILD it is.
4
+ *
5
+ * THE BLENDER IN THE TAB IS BLENDER (ARCHITECTURE-CORE, owner ruling
6
+ * 2026-09-17), and since the 2026-09-18 amendment there are two builds of it:
7
+ *
8
+ * emscripten — the STANDALONE skew, and the one `@volter/blender-engine` SHIPS under
9
+ * `wasm/`: the glue as text plus the two large files pre-compressed
10
+ * (`blender_browser.wasm.br`, `blender_browser.data.br`, ~38 MB together
11
+ * against ~156 MB raw). They are served as-is with `Content-Encoding: br`;
12
+ * the browser decompresses before the runtime sees a byte, so the glue's
13
+ * own `instantiateStreaming` and `.data` preload run unchanged.
14
+ *
15
+ * wali — the SUBSTRATE skew: one `blender.wasm` linked for
16
+ * `wasm32-wali-linux-musl` beside the `runtime/` tree it reads through
17
+ * `BLENDER_SYSTEM_*` (browser-substrate `programs/blender/5.2.0`, whose
18
+ * `gate.sh` stages exactly that pair).
19
+ *
20
+ * THE SKEW IS NOT CONFIGURED, IT IS READ. One editor serves one Blender, and
21
+ * the served directory holds either `blender_browser.js` or `blender.wasm`;
22
+ * that IS the answer, and `status` carries it. There is no manifest field, no
23
+ * setting and no flag, because nothing a user does may depend on the skew —
24
+ * the ruling's "a skew may refuse a capability by name, never answer the same
25
+ * question differently" leaves nothing for a chooser to choose.
26
+ * `VGAI_BLENDER_WASM_DIR` is the existing door for pointing the editor at a
27
+ * different build, and pointing it at a WALI pack is how the substrate skew is
28
+ * reached in development.
29
+ *
30
+ * ONE PATCH IS APPLIED TO THE EMSCRIPTEN GLUE, and it is applied HERE rather
31
+ * than in the worker so that the pthread workers — which the runtime spawns by
32
+ * loading this same URL as a classic worker (`Module.mainScriptUrlOrBlob`) —
33
+ * get the identical text. The build is `-sPROXY_TO_PTHREAD`, and its
34
+ * `pthread_create` glue transfers a `#canvas` to the spawned thread by default.
35
+ * There is no canvas in a worker, and the transfer aborts the spawn, so the
36
+ * transfer list is emptied. The upstream release already does exactly this for
37
+ * node (`if(ENVIRONMENT_IS_NODE){transferredCanvasNames=0}`); a worker needs
38
+ * the same, and for the same reason.
39
+ *
40
+ * THE SAME PATCHING IS WHAT CARRIES THE SUBSTRATE, and it is the precedent
41
+ * being transcribed rather than a new mechanism: `@volter/browser-wali` and
42
+ * `@volter/browser-runtime` are served out of this door too
43
+ * (`/__editor/blender-wasm/wali/<package>/<file>.js`), with their bare
44
+ * `@volter/...` specifiers rewritten to those URLs on the way out. That is
45
+ * what keeps `@volter/blender-engine` free of any dependency on browser-substrate: the
46
+ * standalone skew installs nothing, bundles nothing and fetches nothing, and
47
+ * the WALI engine imports the substrate from URLs instead of specifiers. The
48
+ * nested workers `BrowserWaliWorkerProgram` spawns load from these same URLs,
49
+ * so they get the identical rewritten text — exactly the reason the glue patch
50
+ * lives here.
51
+ *
52
+ * A missing directory is a LOUD 404 naming the variable, never a silent
53
+ * fall-through: the engine either is Blender or says why it is not.
54
+ */
55
+ import { createHash } from 'node:crypto';
56
+ import { createReadStream, existsSync } from 'node:fs';
57
+ import { readdir, readFile, stat } from 'node:fs/promises';
58
+ import { dirname, isAbsolute, join, posix, relative } from 'node:path';
59
+ import { fileURLToPath } from 'node:url';
60
+ import { brotliDecompressSync } from 'node:zlib';
61
+
62
+ export type BlenderSkew = 'emscripten' | 'wali';
63
+
64
+ /** The three files the Emscripten runtime asks for, by the names the glue uses. */
65
+ export const BLENDER_WASM_FILES = [
66
+ 'blender_browser.js',
67
+ 'blender_browser.wasm',
68
+ 'blender_browser.data',
69
+ ] as const;
70
+
71
+ export type BlenderWasmFile = (typeof BLENDER_WASM_FILES)[number];
72
+
73
+ /** What the WALI skew's directory must hold: the artifact, and the runtime
74
+ * tree Blender reads through `BLENDER_SYSTEM_*`. */
75
+ export const BLENDER_WALI_ARTIFACT = 'blender.wasm';
76
+ export const BLENDER_WALI_RUNTIME = 'runtime';
77
+
78
+ /**
79
+ * THE THREAD BUDGET, stated once, here, because it is a property of this RUN
80
+ * SURFACE and not of the program.
81
+ *
82
+ * Blender is SERIAL unless it is told `-t N` and says so on stderr
83
+ * (browser-substrate `programs/blender/5.2.0/README.md` §(a): `-t N` sets
84
+ * oneTBB's global control and blenlib's explicitly sized arena). The POOL is a
85
+ * different number and must be comfortably above it: measured 2026-09-18 in
86
+ * the pack's own emulator, `blender -t 4` TRAPS with a host pool of 4, because
87
+ * the stated count buys four oneTBB workers and Blender starts threads of its
88
+ * own besides. 4 in a pool of 16 is the pair this lane measured end to end
89
+ * (`blender-n-gate`, 2026-09-19: boot 12.0 s, first request 0.9 s, later calls
90
+ * ~1.5 s), and a pool of 8 under `-t 4` trapped during boot on this box.
91
+ */
92
+ /**
93
+ * FOUR, MEASURED, NOT THE MACHINE'S CORES. The Emscripten skew runs Blender at 6
94
+ * on this 12-core box; measured 2026-09-20 on the same operations, WALI at 12
95
+ * threads was SLOWER than at 4 everywhere (subsurf level 6: 40 ms against 17;
96
+ * an ico sphere: 30 against 15; the courtyard 31.1 s against 28.6) -- the
97
+ * pool's scheduling costs more than the cores return, so more `-t` is not more
98
+ * speed here. The pool stays four times the count, the ratio that measured
99
+ * clean (16 under 4; 8 under 4 trapped at boot), because Blender starts threads
100
+ * of its own beyond the oneTBB workers `-t` buys.
101
+ */
102
+ export const BLENDER_WALI_WORKERS = { pool: 16, blender: 4 } as const;
103
+
104
+ /** The substrate packages the WALI engine imports, by the URL segment each is
105
+ * served under and the specifier prefix rewritten to it. */
106
+ export const BLENDER_WALI_SUBSTRATE = [
107
+ { segment: 'browser-wali', specifier: '@volter/browser-wali' },
108
+ { segment: 'browser-runtime', specifier: '@volter/browser-runtime' },
109
+ ] as const;
110
+
111
+ export const BLENDER_WASM_DIR_VARIABLE = 'VGAI_BLENDER_WASM_DIR';
112
+
113
+ /**
114
+ * The bundle `@volter/blender-engine` ships — Blender itself, so its own GPL
115
+ * package (ARCHITECTURE-CORE §Licensing, "Blender's licence stops at the
116
+ * wire"). This resolution is a PATH, not an import: the editor serves those
117
+ * bytes and never imports the engine. `import.meta.url` is THIS FILE in a
118
+ * checkout (`packages/editor/server/`) and the esbuild bundle
119
+ * (`<pkg>/dist-server/packaged.mjs`) in a registry install; from either, two
120
+ * directories up and across is the sibling package -- `packages/blender-engine/wasm`
121
+ * in a checkout, `node_modules/@volter/blender-engine/wasm` installed. Existence is
122
+ * checked once so a realm that lacks it gets a named absence, not a path.
123
+ */
124
+ export const SHIPPED_BLENDER_WASM_DIR: string | null = (() => {
125
+ const candidate = fileURLToPath(new URL('../../blender-engine/wasm/', import.meta.url));
126
+ return existsSync(candidate) ? candidate.replace(/\/$/, '') : null;
127
+ })();
128
+
129
+ /** Where the build is: the named directory, else the shipped one, else null. */
130
+ export function blenderWasmDir(env: NodeJS.ProcessEnv = process.env): string | null {
131
+ const named = env[BLENDER_WASM_DIR_VARIABLE];
132
+ if (typeof named === 'string' && named.trim() !== '') {
133
+ const dir = named.trim();
134
+ return isAbsolute(dir) ? dir : null;
135
+ }
136
+ return SHIPPED_BLENDER_WASM_DIR;
137
+ }
138
+
139
+ /** A file on disk as the build stores it: raw, or pre-compressed as `.br`. */
140
+ export interface BlenderWasmOnDisk {
141
+ path: string;
142
+ size: number;
143
+ encoding: 'br' | null;
144
+ }
145
+
146
+ export async function blenderWasmOnDisk(
147
+ dir: string,
148
+ file: string,
149
+ ): Promise<BlenderWasmOnDisk | null> {
150
+ for (const [suffix, encoding] of [
151
+ ['.br', 'br'],
152
+ ['', null],
153
+ ] as const) {
154
+ const path = join(dir, `${file}${suffix}`);
155
+ try {
156
+ const info = await stat(path);
157
+ if (info.isFile()) return { path, size: info.size, encoding };
158
+ } catch {
159
+ /* try the other spelling */
160
+ }
161
+ }
162
+ return null;
163
+ }
164
+
165
+ export interface BlenderWasmStatus {
166
+ available: boolean;
167
+ /** Which build the served directory holds; null when nothing is served. */
168
+ skew: BlenderSkew | null;
169
+ /** The directory that was looked in, or null when the variable is unset. */
170
+ dir: string | null;
171
+ /** On-disk byte sizes of the files, for the ones that are there
172
+ * (the `.br` size when a file is stored pre-compressed). */
173
+ sizes: Record<string, number>;
174
+ /** Which files are stored pre-compressed, by name. */
175
+ encoded: Record<string, 'br'>;
176
+ /** Why it is unavailable, named. Empty when it is available. */
177
+ missing: string[];
178
+ /** WALI only: the `sha256-` SRI of `blender.wasm`. The program loader
179
+ * refuses any non-blob URL without one, so the session names the exact
180
+ * bytes it ran. */
181
+ integrity?: string;
182
+ /** WALI only: {@link BLENDER_WALI_WORKERS}. */
183
+ workers?: { pool: number; blender: number };
184
+ }
185
+
186
+ /** Which skew a directory holds, by what is in it. Null when it holds neither,
187
+ * which is what `missing` then has to explain. */
188
+ async function skewOf(dir: string): Promise<BlenderSkew | null> {
189
+ if (await blenderWasmOnDisk(dir, 'blender_browser.js')) return 'emscripten';
190
+ if (existsSync(join(dir, BLENDER_WALI_ARTIFACT))) return 'wali';
191
+ return null;
192
+ }
193
+
194
+ export async function blenderWasmStatus(
195
+ env: NodeJS.ProcessEnv = process.env,
196
+ ): Promise<BlenderWasmStatus> {
197
+ const dir = blenderWasmDir(env);
198
+ if (dir === null)
199
+ return {
200
+ available: false,
201
+ skew: null,
202
+ dir: null,
203
+ sizes: {},
204
+ encoded: {},
205
+ missing: [
206
+ `no packages/blender-engine/wasm beside this editor, and ${BLENDER_WASM_DIR_VARIABLE} ` +
207
+ `is not set to an absolute directory holding either ${BLENDER_WASM_FILES.join(', ')} ` +
208
+ `or ${BLENDER_WALI_ARTIFACT} beside its ${BLENDER_WALI_RUNTIME}/ tree`,
209
+ ],
210
+ };
211
+ const skew = await skewOf(dir);
212
+ if (skew === null)
213
+ return {
214
+ available: false,
215
+ skew: null,
216
+ dir,
217
+ sizes: {},
218
+ encoded: {},
219
+ missing: [
220
+ `${dir} holds neither ${BLENDER_WASM_FILES.join(', ')} (the standalone skew) nor ` +
221
+ `${BLENDER_WALI_ARTIFACT} (the substrate skew)`,
222
+ ],
223
+ };
224
+ return skew === 'wali' ? waliStatus(dir) : emscriptenStatus(dir);
225
+ }
226
+
227
+ async function emscriptenStatus(dir: string): Promise<BlenderWasmStatus> {
228
+ const sizes: Record<string, number> = {};
229
+ const encoded: Record<string, 'br'> = {};
230
+ const missing: string[] = [];
231
+ for (const file of BLENDER_WASM_FILES) {
232
+ const found = await blenderWasmOnDisk(dir, file);
233
+ if (!found) {
234
+ missing.push(`${join(dir, file)} (or .br)`);
235
+ continue;
236
+ }
237
+ sizes[file] = found.size;
238
+ if (found.encoding) encoded[file] = found.encoding;
239
+ }
240
+ return { available: missing.length === 0, skew: 'emscripten', dir, sizes, encoded, missing };
241
+ }
242
+
243
+ async function waliStatus(dir: string): Promise<BlenderWasmStatus> {
244
+ const sizes: Record<string, number> = {};
245
+ const missing: string[] = [];
246
+ const artifact = join(dir, BLENDER_WALI_ARTIFACT);
247
+ try {
248
+ sizes[BLENDER_WALI_ARTIFACT] = (await stat(artifact)).size;
249
+ } catch {
250
+ missing.push(artifact);
251
+ }
252
+ let index: RuntimeIndex | null = null;
253
+ try {
254
+ index = await runtimeIndex(dir);
255
+ sizes[`${BLENDER_WALI_RUNTIME}/`] = index.files.reduce((total, file) => total + file.size, 0);
256
+ } catch (error) {
257
+ missing.push(
258
+ `${join(dir, BLENDER_WALI_RUNTIME)} (Blender's scripts, datafiles and python; ` +
259
+ `${error instanceof Error ? error.message : String(error)})`,
260
+ );
261
+ }
262
+ for (const { segment, specifier } of BLENDER_WALI_SUBSTRATE)
263
+ if (substrateDir(specifier) === null)
264
+ missing.push(
265
+ `${specifier} (served at wali/${segment}/; the substrate skew runs Blender through it, ` +
266
+ `so a project that opts into this skew declares it)`,
267
+ );
268
+ const integrity =
269
+ missing.length === 0
270
+ ? `sha256-${createHash('sha256')
271
+ .update(await readFile(artifact))
272
+ .digest('base64')}`
273
+ : undefined;
274
+ return {
275
+ available: missing.length === 0,
276
+ skew: 'wali',
277
+ dir,
278
+ sizes,
279
+ encoded: {},
280
+ missing,
281
+ ...(integrity ? { integrity } : {}),
282
+ workers: { ...BLENDER_WALI_WORKERS },
283
+ };
284
+ }
285
+
286
+ /**
287
+ * The glue, patched. Read once and held: it is 700 KB of text and every
288
+ * pthread the runtime spawns asks for it again.
289
+ */
290
+ let patchedGlue: { dir: string; text: string } | null = null;
291
+
292
+ const CANVAS_TRANSFER =
293
+ 'var transferredCanvasNames=attr?(growMemViews(),HEAPU32)[attr+40>>2]:0;if(';
294
+
295
+ export function patchBlenderGlue(source: string): string {
296
+ // A headless build spawns no window and its glue carries no canvas transfer:
297
+ // then there is nothing to patch and the glue is served as-is. Only a build
298
+ // that DOES transfer a `#canvas` (the port's UI-derived release) needs the
299
+ // list emptied, because a worker has no canvas and `#canvas` asks
300
+ // `Module.canvas` for one that is not there.
301
+ if (!source.includes(CANVAS_TRANSFER)) return source;
302
+ return source.replace(
303
+ CANVAS_TRANSFER,
304
+ `${CANVAS_TRANSFER}true){transferredCanvasNames=0}else if(`,
305
+ );
306
+ }
307
+
308
+ export async function blenderGlueText(dir: string): Promise<string> {
309
+ if (patchedGlue?.dir === dir) return patchedGlue.text;
310
+ const found = await blenderWasmOnDisk(dir, 'blender_browser.js');
311
+ if (!found) throw new Error(`${join(dir, 'blender_browser.js')} is not there`);
312
+ const raw = await readFile(found.path);
313
+ // The glue is patched as TEXT, so a pre-compressed glue is inflated here.
314
+ const source =
315
+ found.encoding === 'br' ? brotliDecompressSync(raw).toString('utf8') : raw.toString('utf8');
316
+ const text = patchBlenderGlue(source);
317
+ patchedGlue = { dir, text };
318
+ return text;
319
+ }
320
+
321
+ export function blenderWasmReadStream(found: BlenderWasmOnDisk): NodeJS.ReadableStream {
322
+ return createReadStream(found.path);
323
+ }
324
+
325
+ // ---- The WALI skew: the runtime tree, and the substrate that runs the program.
326
+
327
+ export interface RuntimeIndex {
328
+ files: { path: string; size: number; mode: number }[];
329
+ }
330
+
331
+ let cachedRuntimeIndex: { dir: string; index: RuntimeIndex } | null = null;
332
+
333
+ /**
334
+ * Blender's runtime tree, as ONE index plus ONE blob.
335
+ *
336
+ * ~2,300 files and 78 MB, every one of which has to exist before Blender's
337
+ * first act. The tab fetches this index and then `runtime.bin`, whose bytes
338
+ * are the same files concatenated IN THIS ORDER, and slices
339
+ * (`blender-wali-engine.mts`'s `stageRuntime`). A request per file would be
340
+ * 2,300 round trips; a tar would be a dependency and a decoder. The order is
341
+ * the index's and nothing else may assume it.
342
+ */
343
+ export async function runtimeIndex(dir: string): Promise<RuntimeIndex> {
344
+ if (cachedRuntimeIndex?.dir === dir) return cachedRuntimeIndex.index;
345
+ const root = join(dir, BLENDER_WALI_RUNTIME);
346
+ const files: RuntimeIndex['files'] = [];
347
+ const walk = async (where: string): Promise<void> => {
348
+ for (const entry of (await readdir(where, { withFileTypes: true })).sort((left, right) =>
349
+ left.name < right.name ? -1 : left.name > right.name ? 1 : 0,
350
+ )) {
351
+ const path = join(where, entry.name);
352
+ if (entry.isDirectory()) {
353
+ await walk(path);
354
+ continue;
355
+ }
356
+ if (!entry.isFile()) continue;
357
+ const info = await stat(path);
358
+ files.push({
359
+ path: relative(root, path).split(/[\\/]/).join(posix.sep),
360
+ size: info.size,
361
+ mode: info.mode & 0o7777,
362
+ });
363
+ }
364
+ };
365
+ await walk(root);
366
+ if (files.length === 0) throw new Error(`${root} is empty`);
367
+ const index = { files };
368
+ cachedRuntimeIndex = { dir, index };
369
+ return index;
370
+ }
371
+
372
+ /** Stream the runtime blob: every indexed file's bytes, in index order. */
373
+ export async function writeRuntimeBlob(dir: string, write: (chunk: Buffer) => void): Promise<void> {
374
+ const root = join(dir, BLENDER_WALI_RUNTIME);
375
+ for (const file of (await runtimeIndex(dir)).files) write(await readFile(join(root, file.path)));
376
+ }
377
+
378
+ /**
379
+ * Where a substrate package's browser ESM is, or null when it is not
380
+ * installed. Resolved through Node's own resolution from THIS file, so it
381
+ * finds whatever the project that opted into this skew declared.
382
+ *
383
+ * `import.meta.resolve` and not `createRequire().resolve`: these packages
384
+ * export `"."` and `"./*.js"` under the `import` condition ONLY, so a CJS
385
+ * resolve raises ERR_PACKAGE_PATH_NOT_EXPORTED on a package that is plainly
386
+ * installed. The package's OWN ENTRY is resolved rather than its
387
+ * `package.json`, which is not exported at all; the entry's directory IS the
388
+ * published `dist`, which is where every served module comes from.
389
+ */
390
+ export function substrateDir(specifier: string): string | null {
391
+ try {
392
+ return dirname(fileURLToPath(import.meta.resolve(specifier)));
393
+ } catch {
394
+ return null;
395
+ }
396
+ }
397
+
398
+ const SUBSTRATE_SEGMENTS = new Map<string, string>(
399
+ BLENDER_WALI_SUBSTRATE.map(({ segment, specifier }) => [segment, specifier] as const),
400
+ );
401
+
402
+ /**
403
+ * One substrate module, with its bare specifiers rewritten to this door's URLs.
404
+ *
405
+ * `@volter/browser-wali/dist/worker-program.js` imports
406
+ * `@volter/browser-runtime/browser-filesystem.js`, which a browser cannot
407
+ * resolve; and `BrowserWaliWorkerProgram` spawns its own workers with
408
+ * `new Worker(new URL("./worker-program-worker.js", import.meta.url))`, so
409
+ * those land back on this same route and must get the identically rewritten
410
+ * text. That is the glue patch's rule applied to a second artifact, for the
411
+ * same reason.
412
+ */
413
+ export async function substrateModule(
414
+ segment: string,
415
+ file: string,
416
+ ): Promise<{ text: string } | null> {
417
+ const specifier = SUBSTRATE_SEGMENTS.get(segment);
418
+ if (!specifier || !/^[\w.-]+\.(?:js|mjs|map)$/.test(file)) return null;
419
+ const root = substrateDir(specifier);
420
+ if (root === null) return null;
421
+ const path = join(root, file);
422
+ if (!existsSync(path)) return null;
423
+ let text = (await readFile(path)).toString('utf8');
424
+ for (const other of BLENDER_WALI_SUBSTRATE)
425
+ text = text.replaceAll(
426
+ `"${other.specifier}/`,
427
+ `"/__editor/blender-wasm/wali/${other.segment}/`,
428
+ );
429
+ return { text };
430
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * "WHERE DID EDITOR BOOT TIME GO" — the one journal row the server writes about
3
+ * its own start-up, emitted when the first browser tab's control channel
4
+ * arrives (`editor-server.ts`, beside `client-connected`).
5
+ *
6
+ * WHY IT EXISTS. `vgai edit` prints two lines — `Editor ready at …` and
7
+ * `Editor page connected …` — and the gap between them is the largest stage of
8
+ * opening a project, with nothing recording it anywhere. Measured 2026-08-20 on
9
+ * an imported Unity FPS port (528 source files): dev-server readiness was 8s and
10
+ * the SAME stage was 83–139s, and answering "why" needed a hand-built request
11
+ * trace plus a V8 CPU profile of the dev server. The cause turned out to be the
12
+ * server's own event loop blocked ~85% of two minutes inside the TypeScript
13
+ * parser (`ui-source/r3f-project-contracts.ts`) — which is exactly the shape a
14
+ * loop-delay number reports for free. A product whose slow stage can only be
15
+ * diagnosed by attaching a profiler is missing a door; this is that door.
16
+ *
17
+ * WHAT IT COSTS. One `monitorEventLoopDelay` histogram — a libuv-side C++
18
+ * sampler, not a JS timer — plus five `Date.now()` marks. `disable()` runs at
19
+ * the first bind, so nothing here outlives boot.
20
+ *
21
+ * `loopDelayP99Ms` IS THE DISCRIMINATING FIELD, and the reason the row is not
22
+ * just a list of stage durations: a slow bind with a quiet loop is the browser
23
+ * (or the network, or a hidden tab); a slow bind with a p99 in the hundreds of
24
+ * ms is THIS process refusing to answer, and every per-request duration in that
25
+ * window is queueing rather than work. Reading them the other way around is the
26
+ * mistake this row prevents — a 38s response for a static `.svg` measured
27
+ * nothing about the svg.
28
+ */
29
+ import { type IntervalHistogram, monitorEventLoopDelay } from 'node:perf_hooks';
30
+
31
+ /** Every span in the boot, in the order a reader should think about them. */
32
+ export interface EditorBootTimings {
33
+ /** Process start → Vite's `createServer` resolved. */
34
+ readonly viteMs: number;
35
+ /** …→ the dependency scan settled (the barrier `dev.ts` awaits before listen). */
36
+ readonly depScanMs: number;
37
+ /** …→ the HTTP server was listening (what `Editor ready at` announces). */
38
+ readonly listenMs: number;
39
+ /**
40
+ * Listening → the first page that PROVED it is running the editor document
41
+ * (its command listener attached). Deliberately not the control channel:
42
+ * `index.html`'s inline bootstrap opens that before any module loads, so it
43
+ * dates the HTML, not the app.
44
+ */
45
+ readonly boundMs: number;
46
+ /**
47
+ * Process start → the project's declared world warmup finished; `null` when
48
+ * no project was open to warm. On the same clock as the marks above on
49
+ * purpose: the warmup is kicked off right after `depScanMs` and deliberately
50
+ * NOT awaited, so what a reader needs is where it LANDS relative to the
51
+ * bind — before it (free) or across it (competing with the browser).
52
+ */
53
+ readonly worldWarmupDoneMs: number | null;
54
+ /** Event-loop delay across the whole boot. A high p99 means the SERVER was the wait. */
55
+ readonly loopDelayP99Ms: number;
56
+ readonly loopDelayMaxMs: number;
57
+ }
58
+
59
+ export type EditorBootMark = 'vite-created' | 'dep-scan-settled' | 'listening' | 'world-warmup';
60
+
61
+ export interface EditorBootTimer {
62
+ mark(name: EditorBootMark): void;
63
+ /**
64
+ * The row, ONCE — the first page to prove it is running the document ends
65
+ * the boot, and a later reload is not a second boot. `null` on every call
66
+ * after that, and on a call that arrives before `listening` was ever marked.
67
+ */
68
+ takeBoundTimings(): EditorBootTimings | null;
69
+ }
70
+
71
+ export function createEditorBootTimer(startedAt: number = Date.now()): EditorBootTimer {
72
+ const marks = new Map<EditorBootMark, number>();
73
+ let loop: IntervalHistogram | null = null;
74
+ try {
75
+ loop = monitorEventLoopDelay({ resolution: 20 });
76
+ loop.enable();
77
+ } catch {
78
+ // A runtime without the histogram still gets every other field.
79
+ loop = null;
80
+ }
81
+ let taken = false;
82
+
83
+ return {
84
+ mark(name) {
85
+ if (!marks.has(name)) marks.set(name, Date.now());
86
+ },
87
+ takeBoundTimings() {
88
+ const listening = marks.get('listening');
89
+ if (taken || listening === undefined) return null;
90
+ taken = true;
91
+ const now = Date.now();
92
+ loop?.disable();
93
+ const warmup = marks.get('world-warmup');
94
+ return {
95
+ viteMs: (marks.get('vite-created') ?? startedAt) - startedAt,
96
+ depScanMs: (marks.get('dep-scan-settled') ?? startedAt) - startedAt,
97
+ listenMs: listening - startedAt,
98
+ boundMs: now - listening,
99
+ worldWarmupDoneMs: warmup === undefined ? null : warmup - startedAt,
100
+ // The histogram reports NANOSECONDS.
101
+ loopDelayP99Ms: loop === null ? 0 : Math.round(loop.percentile(99) / 1e6),
102
+ loopDelayMaxMs: loop === null ? 0 : Math.round(loop.max / 1e6),
103
+ };
104
+ },
105
+ };
106
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Canonicalize a project root path (T6.2 slice 3 finding; reported in the
3
+ * slice-3 "Report back").
4
+ *
5
+ * Vite's own module resolver calls `fs.realpathSync` when resolving a
6
+ * STATIC relative import — e.g. a react world's entry module's own
7
+ * `import { useWorldState } from '@vgai/game-runtime/react/world-state'` — which
8
+ * collapses a symlinked path segment (macOS's `/var` -> `/private/var`,
9
+ * hit by every project scaffolded under `os.tmpdir()`, as every e2e spec
10
+ * that calls `scaffoldProject()` does) to its real form.
11
+ * `binding-resolver.ts`'s hand-built `/@fs/${projectRoot}/...` dynamic-import
12
+ * strings (which must bypass Vite's static analysis via `@vite-ignore` — the
13
+ * path is only known at runtime) do NOT go through that same resolution. So
14
+ * if `projectRoot` itself isn't already canonical, two DIFFERENT `/@fs/`
15
+ * URLs get produced for the exact same file: Vite's realpath'd rewrite of
16
+ * the entry module's own relative import vs. our raw, non-realpath'd string
17
+ * used to import `WorldProvider` for the `<WorldProvider>` wrap. Browser ES
18
+ * module identity is per-URL, so the SAME `game-state.tsx` loads as TWO
19
+ * separate module instances with TWO separate top-level `createContext()`
20
+ * calls — `useWorldState`'s `useGame()` then throws "no Game in context"
21
+ * even though `<WorldProvider>` genuinely wraps the entry (this is exactly
22
+ * what the T6.2 slice-3 AC e2e's first real-browser run of a react world
23
+ * caught).
24
+ *
25
+ * The fix is upstream of any one `/@fs/` string: canonicalize the project
26
+ * root ONCE, at the points a project path enters server state (dev/prod
27
+ * boot from `VGAI_PROJECT`, and the `/__editor/open-project` route) — every
28
+ * `/@fs/${projectRoot}` string built anywhere afterwards (browser-side,
29
+ * repo-wide, not just the react-world resolver) then already matches
30
+ * whatever Vite's own resolver would independently arrive at for that same
31
+ * project.
32
+ */
33
+ import { realpathSync } from 'node:fs';
34
+ import { resolve } from 'node:path';
35
+
36
+ /**
37
+ * Resolve `rawPath` to an absolute, symlink-canonicalized path. Falls back to
38
+ * a plain `path.resolve` if the path doesn't exist yet or `realpathSync`
39
+ * otherwise fails (e.g. a permissions error) — never throws, so a bad/odd
40
+ * path degrades to today's pre-canonicalization behavior rather than
41
+ * blocking project open.
42
+ */
43
+ export function canonicalProjectRoot(rawPath: string): string {
44
+ const absolute = resolve(rawPath);
45
+ try {
46
+ return realpathSync(absolute);
47
+ } catch {
48
+ return absolute;
49
+ }
50
+ }