@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,172 @@
1
+ /**
2
+ * WHAT A THREE WORLD CAN SHOW AT A TIME — the stage transport's subjects for
3
+ * an ordinary three/R3F stage (WORK.md §The stage transport and the animation
4
+ * door, Step 3).
5
+ *
6
+ * TWO DISCOVERIES, because a three world carries clips in two different
7
+ * places and only one of them is the obvious one:
8
+ *
9
+ * 1. `object.animations` — what a GLTF's own `AnimationClip[]` lands in when
10
+ * something assigns it. A subject here owns a NEW `AnimationMixer` on that
11
+ * object, because nothing else is playing it.
12
+ * 2. `getUserData(object, '_animationRuntime')` — the inspection a world's
13
+ * own binding attached (`bindXStateAnimation` →
14
+ * `attachAnimationRuntimeInspection`). A subject here drives THAT
15
+ * inspection's existing mixer; minting a second mixer over the same object
16
+ * would give one skeleton two writers.
17
+ *
18
+ * DISCOVERY 2 IS NOT OPTIONAL, and this is the measurement that says so:
19
+ * three's `GLTFLoader` never assigns `scene.animations`, so an R3F character
20
+ * loaded with `useGLTF` has an EMPTY `animations` array on its Object3D. A
21
+ * scan that looked only at `animations` would find nothing on exactly the
22
+ * worlds a person most wants to scrub.
23
+ *
24
+ * THE MIXER IS THREE'S OWN and every call here is three's own API — this is a
25
+ * subject over `AnimationMixer`, never a wrapper around it. `setTime` is the
26
+ * one write; the transport owns the position.
27
+ */
28
+ import { getUserData } from '@volter/editor-threejs/ecs/user-data';
29
+ import * as THREE from 'three';
30
+ import type { StageTransport } from './stage-transport';
31
+
32
+ /** The display rate a three clip is shown at. Three clips carry a duration in
33
+ * SECONDS and no rate of their own, so the transport needs one to convert a
34
+ * frame for a look that asks in frames. 30 is three's own editor convention
35
+ * (`AnimationClip.CreateFromMorphTargetSequence` defaults to it). */
36
+ const THREE_DISPLAY_FPS = 30;
37
+
38
+ function clamp(value: number, min: number, max: number): number {
39
+ return value < min ? min : value > max ? max : value;
40
+ }
41
+
42
+ /**
43
+ * A subject over an object's OWN clips, on a mixer this subject mints and
44
+ * owns. `setClip` swaps which clip is showing: the chosen action is played
45
+ * PAUSED (so it poses the skeleton without advancing itself) and every other
46
+ * action is stopped, because the transport — not the action — is what moves.
47
+ */
48
+ function attachOwnClips(object: THREE.Object3D, transport: StageTransport): (() => void) | null {
49
+ const clips = object.animations;
50
+ if (clips.length === 0) return null;
51
+ const mixer = new THREE.AnimationMixer(object);
52
+ let current = clips[0];
53
+ if (!current) return null;
54
+
55
+ const show = (clip: THREE.AnimationClip): void => {
56
+ mixer.stopAllAction();
57
+ const action = mixer.clipAction(clip);
58
+ action.paused = true;
59
+ action.play();
60
+ current = clip;
61
+ };
62
+ show(current);
63
+
64
+ const detach = transport.attach({
65
+ id: object.uuid,
66
+ label: object.name || current.name || 'Clip',
67
+ range: () => ({ start: 0, end: current?.duration ?? 0, fps: THREE_DISPLAY_FPS }),
68
+ seek: (seconds) => {
69
+ mixer.setTime(clamp(seconds, 0, current?.duration ?? 0));
70
+ },
71
+ clips: () => clips.map((clip) => ({ id: clip.name, label: clip.name })),
72
+ setClip: (id) => {
73
+ const next = clips.find((clip) => clip.name === id);
74
+ if (next) show(next);
75
+ },
76
+ });
77
+
78
+ return () => {
79
+ detach();
80
+ mixer.stopAllAction();
81
+ mixer.uncacheRoot(object);
82
+ };
83
+ }
84
+
85
+ /**
86
+ * A subject over an inspection a world's own binding already owns. It drives
87
+ * that mixer and never mints one; `clips` come from the inspection's map.
88
+ */
89
+ function attachInspected(object: THREE.Object3D, transport: StageTransport): (() => void) | null {
90
+ const inspection = getUserData(object, '_animationRuntime');
91
+ if (!inspection) return null;
92
+ const entries = [...inspection.clips.entries()];
93
+ let current = entries[0]?.[1];
94
+ if (!current) return null;
95
+
96
+ const show = (clip: THREE.AnimationClip): void => {
97
+ inspection.mixer.stopAllAction();
98
+ const action = inspection.mixer.clipAction(clip);
99
+ action.paused = true;
100
+ action.play();
101
+ current = clip;
102
+ };
103
+
104
+ const detach = transport.attach({
105
+ id: object.uuid,
106
+ label: object.name || current.name || 'Animation',
107
+ range: () => ({ start: 0, end: current?.duration ?? 0, fps: THREE_DISPLAY_FPS }),
108
+ seek: (seconds) => {
109
+ inspection.mixer.setTime(clamp(seconds, 0, current?.duration ?? 0));
110
+ },
111
+ clips: () => entries.map(([name, clip]) => ({ id: name, label: clip.name || name })),
112
+ setClip: (id) => {
113
+ const next = inspection.clips.get(id);
114
+ if (next) show(next);
115
+ },
116
+ });
117
+
118
+ // Deliberately NOT stopping the inspection's actions on detach: this subject
119
+ // borrowed a mixer the world owns, and a borrower does not decide what the
120
+ // owner is playing when it leaves.
121
+ return detach;
122
+ }
123
+
124
+ /**
125
+ * One scan of a mounted root, and the handle that keeps it current.
126
+ *
127
+ * `refresh()` DIFFS by object uuid rather than re-attaching: a rescan of an
128
+ * unchanged tree must not detach and re-attach every subject, because that
129
+ * would reset which clip each one is showing under a person's hands. The
130
+ * caller decides when to rescan (the stage host throttles it and skips it
131
+ * while the world is driving time).
132
+ */
133
+ export interface ClipSubjectScan {
134
+ refresh(): void;
135
+ dispose(): void;
136
+ }
137
+
138
+ export function scanClipSubjects(root: THREE.Object3D, transport: StageTransport): ClipSubjectScan {
139
+ const attached = new Map<string, () => void>();
140
+
141
+ const refresh = (): void => {
142
+ const seen = new Set<string>();
143
+ root.traverse((object) => {
144
+ if (attached.has(object.uuid)) {
145
+ seen.add(object.uuid);
146
+ return;
147
+ }
148
+ // The inspection wins when an object has both: it means a world binding
149
+ // is already driving that skeleton, and a second mixer over it would
150
+ // give one object two writers.
151
+ const detach = attachInspected(object, transport) ?? attachOwnClips(object, transport);
152
+ if (!detach) return;
153
+ attached.set(object.uuid, detach);
154
+ seen.add(object.uuid);
155
+ });
156
+ for (const [uuid, detach] of [...attached]) {
157
+ if (seen.has(uuid)) continue;
158
+ detach();
159
+ attached.delete(uuid);
160
+ }
161
+ };
162
+
163
+ refresh();
164
+
165
+ return {
166
+ refresh,
167
+ dispose: () => {
168
+ for (const detach of attached.values()) detach();
169
+ attached.clear();
170
+ },
171
+ };
172
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The asset-library wire — the shapes `/__editor/assets/*` answers with,
3
+ * declared ONCE in a leaf module both sides import (the browser client in
4
+ * `./assets.ts`, the producing routes in `../../server/asset-library-routes.ts`).
5
+ * Deliberately import-free so the server's tsconfig can reach it without
6
+ * dragging the client's whole module graph along.
7
+ */
8
+
9
+ export interface OnlineAsset {
10
+ id: string;
11
+ source: 'polyhaven' | 'ambientcg' | 'local';
12
+ name: string;
13
+ type: 'model' | 'animation' | 'source' | 'hdri' | 'texture' | 'material';
14
+ thumbnailUrl: string;
15
+ categories: string[];
16
+ tags: string[];
17
+ downloadCount?: number;
18
+ license?: string;
19
+ author?: string;
20
+ sourceUrl?: string;
21
+ cloudHosted?: boolean;
22
+ variantId?: string;
23
+ variantCount?: number;
24
+ sizeBytes?: number;
25
+ animationCount?: number;
26
+ deliveryKinds?: ('local-ssd' | 'cloud' | 'remote')[];
27
+ addedAt?: string;
28
+ capabilities?: {
29
+ previewable: boolean;
30
+ importable: boolean;
31
+ runtimeReady: boolean;
32
+ animated: boolean;
33
+ deliveryAvailable: boolean;
34
+ health: 'healthy' | 'source-only' | 'unsupported';
35
+ };
36
+ }
37
+
38
+ export interface AssetFileOption {
39
+ label: string;
40
+ format: string;
41
+ url: string;
42
+ sizeBytes?: number;
43
+ /** Additional files that must be downloaded alongside the main URL (GLTF includes). */
44
+ includes?: { relativePath: string; url: string; size: number }[];
45
+ }
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Listing project assets, and the online asset library. Both are the session's
3
+ * own routes: it owns the project folder, so it is the one thing that can list
4
+ * `public/` or write a downloaded asset into it.
5
+ */
6
+
7
+ import type { ProjectComponentEntry } from '../asset-workflow/project-content';
8
+
9
+ import { assertEditorServerAnswered, editorServerJson } from '../editor-server-response';
10
+ import { getStorageBackend } from '../storage';
11
+ import { BASE } from './base';
12
+ export interface AssetEntry {
13
+ name: string;
14
+ type: 'file' | 'directory';
15
+ /** Bytes, when the backend reports it. ABSENT means unmeasured — not zero. */
16
+ size?: number;
17
+ /** Epoch ms, when the backend reports it. ABSENT means unmeasured — not 1970. */
18
+ modifiedAt?: number;
19
+ }
20
+
21
+ /**
22
+ * A listing that either HAPPENED or FAILED.
23
+ *
24
+ * `{ ok: true, entries: [] }` is a real measurement — the directory is empty,
25
+ * the project defines no components. A failure is a DIFFERENT FACT and carries
26
+ * its reason, because rendering "this folder is empty" over a permissions
27
+ * error, an offline dev server or a 500 tells the author their work is gone.
28
+ * Both listings used to `catch { return [] }`, so the two were the same bytes.
29
+ */
30
+ export type Listing<T> =
31
+ | { readonly ok: true; readonly entries: T[] }
32
+ | { readonly ok: false; readonly reason: string };
33
+
34
+ function listingFailure(error: unknown): { readonly ok: false; readonly reason: string } {
35
+ return { ok: false, reason: error instanceof Error ? error.message : String(error) };
36
+ }
37
+
38
+ /** One named asset root, listed by the editor server's own route. The entry
39
+ * shape is the route's; an ABSENT root answers the empty listing (the route's
40
+ * own S-8 rule), and a real failure still reports its reason. */
41
+ async function listAssetRootFromServer(root: string, dir: string): Promise<Listing<AssetEntry>> {
42
+ try {
43
+ const query = new URLSearchParams({ root, dir });
44
+ const response = await fetch(`${BASE}/assets?${query}`, { cache: 'no-store' });
45
+ const body = await editorServerJson<{ entries?: AssetEntry[] }>(
46
+ response,
47
+ `Could not list ${root}/${dir} from ${BASE}/assets`,
48
+ );
49
+ return { ok: true, entries: body.entries ?? [] };
50
+ } catch (error) {
51
+ return listingFailure(error);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * List files and folders in a directory under one of the project's asset roots
57
+ * (`public`, or `references` — see `asset-workflow/project-asset-roots.ts`).
58
+ * `dir` is root-relative in both tiers; only the way the root is reached
59
+ * differs, and that difference is the two branches below.
60
+ */
61
+ export async function listAssets(root: string, dir: string): Promise<Listing<AssetEntry>> {
62
+ // The tier's backend is rooted AT `public/`, so a second root cannot be
63
+ // spelled through it at all — it is named to the server's own listing route
64
+ // instead, which resolves it from the open project.
65
+ if (root !== 'public') return listAssetRootFromServer(root, dir);
66
+ try {
67
+ const entries = await getStorageBackend().list(dir);
68
+ return {
69
+ ok: true,
70
+ entries: entries.map((e) => ({
71
+ name: e.name,
72
+ type: e.type === 'dir' ? ('directory' as const) : ('file' as const),
73
+ // OMITTED, never zeroed: a backend that does not report a size has not
74
+ // told us the file is 0 bytes, and a browser listing genuinely cannot
75
+ // for some handles. `0`/`0` sorted an unmeasured file to the bottom of
76
+ // "largest first" and to 1970 in "most recent", both as if measured.
77
+ ...(e.size === undefined ? {} : { size: e.size }),
78
+ ...(e.mtime === undefined ? {} : { modifiedAt: e.mtime }),
79
+ })),
80
+ };
81
+ } catch (error) {
82
+ return listingFailure(error);
83
+ }
84
+ }
85
+
86
+ /** List source-defined visual components for the semantic component board. */
87
+ export async function listProjectComponents(): Promise<Listing<ProjectComponentEntry>> {
88
+ try {
89
+ const response = await fetch(`${BASE}/project-components`, { cache: 'no-store' });
90
+ const body = await editorServerJson<{ components?: ProjectComponentEntry[] }>(
91
+ response,
92
+ `Could not list project components from ${BASE}/project-components`,
93
+ );
94
+ return { ok: true, entries: body.components ?? [] };
95
+ } catch (error) {
96
+ return listingFailure(error);
97
+ }
98
+ }
99
+
100
+ /** Build a download URL for a build artifact. */
101
+ export function getDownloadUrl(file: string): string {
102
+ return `${BASE}/download?file=${encodeURIComponent(file)}`;
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // Asset Library (online browsing + download)
107
+ //
108
+ // The session is a Node-only proxy to Poly Haven/ambientcg (CORS +
109
+ // SSRF-allowlist reasons to stay server-side) plus the 34,412-asset local SSD
110
+ // catalog, writing into `<project>/public/asset-library/...` via raw
111
+ // `node:fs`. A browser cannot do either: it is refused by CORS and has no
112
+ // local disk to read.
113
+ // ---------------------------------------------------------------------------
114
+
115
+ import type { AssetFileOption, OnlineAsset } from './asset-library-wire';
116
+
117
+ export type { AssetFileOption, OnlineAsset } from './asset-library-wire';
118
+
119
+ export type AssetDeliveryIssueCode =
120
+ | 'offline'
121
+ | 'quota-limited'
122
+ | 'license-blocked'
123
+ | 'unavailable'
124
+ | 'provider-error';
125
+
126
+ export class AssetDeliveryError extends Error {
127
+ constructor(
128
+ readonly code: AssetDeliveryIssueCode,
129
+ message: string,
130
+ ) {
131
+ super(message);
132
+ this.name = 'AssetDeliveryError';
133
+ }
134
+ }
135
+
136
+ export function assetDeliveryIssueMessage(code: AssetDeliveryIssueCode): string {
137
+ return {
138
+ offline: 'Network delivery is offline. SSD assets remain available.',
139
+ 'quota-limited': 'The remote provider quota is exhausted. Retry after the provider resets it.',
140
+ 'license-blocked': 'This delivery is blocked because its license terms are not accepted.',
141
+ unavailable: 'No healthy SSD, cloud, or remote delivery is available for this variant.',
142
+ 'provider-error': 'The remote provider could not return delivery metadata. Retry the request.',
143
+ }[code];
144
+ }
145
+
146
+ export interface OnlineAssetPreview {
147
+ path: string;
148
+ format: string;
149
+ label: string;
150
+ sourceAssetId: string;
151
+ materialPath?: string;
152
+ }
153
+
154
+ // ---------------------------------------------------------------------------
155
+ // Downloaded-asset cache (client-side, keyed by exact provider identity)
156
+ // ---------------------------------------------------------------------------
157
+
158
+ /** Maps "source:asset-id" → local serving path. Display names are never identity. */
159
+ const downloadedAssetPaths = new Map<string, string>();
160
+
161
+ /** Listeners notified when the download cache changes. */
162
+ const downloadListeners = new Set<() => void>();
163
+
164
+ function assetCacheKey(source: string, assetId: string): string {
165
+ return `${source}:${assetId}`;
166
+ }
167
+
168
+ /** Check if an online asset has already been downloaded. Returns local path or null. */
169
+ export function getDownloadedAssetPath(source: string, assetId: string): string | null {
170
+ return downloadedAssetPaths.get(assetCacheKey(source, assetId)) ?? null;
171
+ }
172
+
173
+ /** Subscribe to download cache changes. Returns unsubscribe function. */
174
+ export function onAssetDownloaded(cb: () => void): () => void {
175
+ downloadListeners.add(cb);
176
+ return () => downloadListeners.delete(cb);
177
+ }
178
+
179
+ /** Fetch already-downloaded assets from the server and seed the cache. */
180
+ export async function loadDownloadedAssets(): Promise<void> {
181
+ try {
182
+ const res = await fetch(`${BASE}/asset-library/downloaded`);
183
+ const data = await editorServerJson<{
184
+ downloaded: { source: string; id: string; path: string }[];
185
+ }>(res, 'Could not read the downloaded-asset list');
186
+ downloadedAssetPaths.clear();
187
+ for (const entry of data.downloaded) {
188
+ downloadedAssetPaths.set(assetCacheKey(entry.source, entry.id), `/${entry.path}`);
189
+ }
190
+ for (const cb of downloadListeners) cb();
191
+ } catch {
192
+ /* best-effort */
193
+ }
194
+ }
195
+
196
+ /** Search for online assets via the editor server's proxy. */
197
+ export async function searchOnlineAssets(params: {
198
+ source: string;
199
+ type: string;
200
+ q?: string;
201
+ category?: string;
202
+ offset?: number;
203
+ limit?: number;
204
+ }): Promise<{ assets: OnlineAsset[]; total: number }> {
205
+ const qs = new URLSearchParams();
206
+ qs.set('source', params.source);
207
+ qs.set('type', params.type);
208
+ if (params.q) qs.set('q', params.q);
209
+ if (params.category) qs.set('category', params.category);
210
+ if (params.offset != null) qs.set('offset', String(params.offset));
211
+ if (params.limit != null) qs.set('limit', String(params.limit));
212
+
213
+ const res = await fetch(`${BASE}/asset-library/search?${qs}`);
214
+ assertEditorServerAnswered(res, 'Asset Library search failed');
215
+ if (!res.ok) {
216
+ const body = (await res.json().catch(() => null)) as { error?: string } | null;
217
+ throw new Error(body?.error ?? `Asset Library search failed (${res.status}).`);
218
+ }
219
+ return (await res.json()) as { assets: OnlineAsset[]; total: number };
220
+ }
221
+
222
+ /** Get available file options (resolutions/formats) for an online asset. */
223
+ export async function getOnlineAssetFiles(source: string, id: string): Promise<AssetFileOption[]> {
224
+ return fetchOnlineAssetFilesFromServer(source, id);
225
+ }
226
+
227
+ async function fetchOnlineAssetFilesFromServer(
228
+ source: string,
229
+ id: string,
230
+ ): Promise<AssetFileOption[]> {
231
+ const qs = new URLSearchParams({ source, id });
232
+ let res: Response;
233
+ try {
234
+ res = await fetch(`${BASE}/asset-library/files?${qs}`);
235
+ } catch (error) {
236
+ throw new AssetDeliveryError(
237
+ 'offline',
238
+ error instanceof Error ? error.message : assetDeliveryIssueMessage('offline'),
239
+ );
240
+ }
241
+ // A page fallback here is not a provider problem — it is nobody serving the
242
+ // route — so it reports itself rather than being graded into a delivery code.
243
+ assertEditorServerAnswered(res, 'Asset Library file lookup failed');
244
+ if (!res.ok) {
245
+ const body = (await res.json().catch(() => null)) as { error?: string } | null;
246
+ const code: AssetDeliveryIssueCode =
247
+ res.status === 403
248
+ ? 'license-blocked'
249
+ : res.status === 429
250
+ ? 'quota-limited'
251
+ : res.status === 404
252
+ ? 'unavailable'
253
+ : 'provider-error';
254
+ throw new AssetDeliveryError(code, body?.error ?? assetDeliveryIssueMessage(code));
255
+ }
256
+ const data = (await res.json()) as { files: AssetFileOption[] };
257
+ return data.files;
258
+ }
259
+
260
+ /** Resolve a read-only interactive model preview from the editor's catalog cache. */
261
+ export async function getOnlineAssetPreview(
262
+ source: string,
263
+ id: string,
264
+ ): Promise<OnlineAssetPreview | null> {
265
+ const qs = new URLSearchParams({ source, id });
266
+ const res = await fetch(`${BASE}/asset-library/preview?${qs}`);
267
+ // `null` stays the answer for a route that says "no preview" (404); it is NOT
268
+ // the answer for an origin where the route does not exist at all.
269
+ assertEditorServerAnswered(res, 'Could not resolve an asset preview');
270
+ if (!res.ok) return null;
271
+ return (await res.json()) as OnlineAssetPreview;
272
+ }
273
+
274
+ export interface AppliedAssetImportHistory {
275
+ assetPath: string;
276
+ beforeToken: string;
277
+ afterToken: string;
278
+ }
279
+
280
+ export interface DownloadOnlineAssetResult {
281
+ ok: boolean;
282
+ path?: string;
283
+ alreadyExists?: boolean;
284
+ provenanceOperationId?: string;
285
+ history?: AppliedAssetImportHistory;
286
+ error?: string;
287
+ /** The import SUCCEEDED but `.vgai/assets.json` could not be updated (D-AP3).
288
+ * Loud, non-fatal degradation: the bytes are in the project, the provenance
289
+ * record is not. */
290
+ ledgerError?: string;
291
+ }
292
+
293
+ /** Download an online asset into the project's public/asset-library/ folder. */
294
+ export async function downloadOnlineAsset(params: {
295
+ source: string;
296
+ id: string;
297
+ name: string;
298
+ url: string;
299
+ format: string;
300
+ jobId?: string;
301
+ includes?: { relativePath: string; url: string; size: number }[];
302
+ /** License as the library's own search result reported it. Recorded in the
303
+ * provenance ledger for sources the server cannot resolve a license for
304
+ * (the polyhaven/ambientcg proxy) — see D-AP3. */
305
+ license?: string;
306
+ signal?: AbortSignal;
307
+ }): Promise<DownloadOnlineAssetResult> {
308
+ const res = await fetch(`${BASE}/asset-library/download`, {
309
+ method: 'POST',
310
+ headers: { 'Content-Type': 'application/json' },
311
+ body: JSON.stringify({ ...params, signal: undefined }),
312
+ ...(params.signal ? { signal: params.signal } : {}),
313
+ });
314
+ assertEditorServerAnswered(res, 'Could not download the asset');
315
+ const result = (await res.json()) as DownloadOnlineAssetResult;
316
+ // Cache the local path on success
317
+ if (result.ok && result.path) {
318
+ downloadedAssetPaths.set(assetCacheKey(params.source, params.id), `/${result.path}`);
319
+ for (const cb of downloadListeners) cb();
320
+ }
321
+ return result;
322
+ }
323
+
324
+ /** Capture a content-addressed server snapshot for one imported asset directory. */
325
+ export async function captureProjectAssetHistory(assetPath: string): Promise<string> {
326
+ const response = await fetch(`${BASE}/asset-library/history/capture`, {
327
+ method: 'POST',
328
+ headers: { 'Content-Type': 'application/json' },
329
+ body: JSON.stringify({ assetPath }),
330
+ });
331
+ assertEditorServerAnswered(response, 'Asset history capture failed');
332
+ const result = (await response.json()) as { ok?: boolean; token?: string; error?: string };
333
+ if (!response.ok || !result.token) {
334
+ throw new Error(result.error ?? `Asset history capture failed (${response.status}).`);
335
+ }
336
+ return result.token;
337
+ }
338
+
339
+ /** Restore an exact imported-directory + provenance snapshot during undo/redo. */
340
+ export async function restoreProjectAssetHistory(assetPath: string, token: string): Promise<void> {
341
+ const response = await fetch(`${BASE}/asset-library/history/restore`, {
342
+ method: 'POST',
343
+ headers: { 'Content-Type': 'application/json' },
344
+ body: JSON.stringify({ assetPath, token }),
345
+ });
346
+ // This function REPORTS BY RETURNING: a page fallback is `ok`, so an undo
347
+ // that restored nothing used to complete silently.
348
+ assertEditorServerAnswered(response, 'Asset history restore failed');
349
+ if (!response.ok) {
350
+ const result = (await response.json().catch(() => null)) as { error?: string } | null;
351
+ throw new Error(result?.error ?? `Asset history restore failed (${response.status}).`);
352
+ }
353
+ }
354
+
355
+ /** Get categories for a given asset type (Poly Haven, or the cloud-hosted
356
+ * "local" catalog). */
357
+ export async function getAssetLibraryCategories(type: string, source?: string): Promise<string[]> {
358
+ const params = new URLSearchParams({ type });
359
+ if (source) params.set('source', source);
360
+ const res = await fetch(`${BASE}/asset-library/categories?${params}`);
361
+ assertEditorServerAnswered(res, 'Could not read Asset Library categories');
362
+ if (!res.ok) return [];
363
+ const data = (await res.json()) as { categories: string[] };
364
+ return data.categories;
365
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * What every `api/<family>.ts` module shares: the route prefix every
3
+ * `/__editor/*` op is written against.
4
+ *
5
+ * The session serves the editor and answers these routes (ARCHITECTURE-CORE
6
+ * §The target shape rule 5), so a family module asks no question before
7
+ * touching the network.
8
+ */
9
+
10
+ export const BASE = '/__editor';
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Producing a build, and the two catalogues the New Project screen starts one
3
+ * from: `/__editor/export`, `/__editor/examples`, `/__editor/templates`.
4
+ */
5
+
6
+ import { editorServerJson } from '../editor-server-response';
7
+ import { BASE } from './base';
8
+ /** Start a build/export. Returns the raw Response for SSE streaming.
9
+ *
10
+ * Deliberately NOT read through `editor-server-response.ts`: that reader's
11
+ * rule is "the editor server answers JSON", and a successful export answers
12
+ * `text/event-stream`, which it would reject. The stream's own consumer owns
13
+ * the question here. */
14
+
15
+ /** FT-5 learner-facing metadata — mirrors the manifest's `learn` block
16
+ * (`LearnMetadataSchema`, @volter/editor-project/manifest/schema); served merged into `GET
17
+ * /__editor/examples`. */
18
+ export interface ExampleLearnInfo {
19
+ kind: 'starter' | 'feature' | 'sample-game' | 'lesson-companion';
20
+ title: string;
21
+ summary: string;
22
+ difficulty: 'beginner' | 'intermediate' | 'advanced';
23
+ features: string[];
24
+ thumbnail?: string;
25
+ preview?: string;
26
+ lesson?: string;
27
+ }
28
+
29
+ export interface ExampleInfo {
30
+ id: string;
31
+ name: string;
32
+ /** The example's FT-5 `learn` block. REQUIRED: every shipped example
33
+ * carries one and the server omits any example that doesn't (editor and
34
+ * server ship from one repo, so there is no older server to be compatible
35
+ * with). */
36
+ learn: ExampleLearnInfo;
37
+ }
38
+
39
+ /** List `examples/<id>/` projects (Track E3, §1.F). Server mode reads the
40
+ * scaffold registry. Browser mode derives the list from what THIS build
41
+ * actually stages: the runtime bundle's per-root dispatch keys name every
42
+ * bundled example, and each one's manifest (with its FT-5 `learn` block) is
43
+ * served at `/examples/<id>/vgai.project.json` — so the gallery lists
44
+ * exactly the projects `?project=<id>` can open, never a curated id that
45
+ * drifted from the build (the dead `editor-tutorial` link, measured on
46
+ * production 2026-08-27, was exactly that drift). */
47
+ export async function listExamples(): Promise<ExampleInfo[]> {
48
+ try {
49
+ const res = await fetch(`${BASE}/examples`);
50
+ const data = await editorServerJson<{ examples: ExampleInfo[] }>(
51
+ res,
52
+ `GET ${BASE}/examples failed`,
53
+ );
54
+ return data.examples;
55
+ } catch {
56
+ return [];
57
+ }
58
+ }
59
+
60
+ /** One template-registry entry (G1, FT-3): mirrors `TemplateRegistryEntry` in
61
+ * create-vgai-project/templates, served by `GET /__editor/templates` from the
62
+ * same `templates.json` the CLI reads. */
63
+ export interface TemplateInfo {
64
+ id: string;
65
+ title: string;
66
+ description: string;
67
+ /** `template:<compositionId>` or `example:<exampleId>`. */
68
+ source: string;
69
+ thumbnail?: string;
70
+ /** Curated preview bullets for composition templates. Promoted examples
71
+ * derive their facts from the owning example's learn metadata. */
72
+ whatsInside?: string[];
73
+ /** A post-copy PRESENTATION of `source`'s tree. The gallery's
74
+ * "Blank" card carries `'blank'` beside the SAME `template:default` source
75
+ * the starter card uses — two cards, one template. */
76
+ presentation?: string;
77
+ }
78
+
79
+ /** Map an engine-repo-relative registry/learn thumbnail path to its server
80
+ * route without baking template or example directories into the client. */
81
+ export function learnThumbnailUrl(repoRelativePath: string): string {
82
+ // Browser-mode example thumbnails are already staged ABSOLUTE paths
83
+ // (`/examples/<id>/learn/…`) — there is no server route to proxy them.
84
+ if (repoRelativePath.startsWith('/')) return repoRelativePath;
85
+ return `${BASE}/learn-thumbnail?file=${encodeURIComponent(repoRelativePath)}`;
86
+ }
87
+
88
+ /** List the template registry. */
89
+ export async function listTemplates(): Promise<TemplateInfo[]> {
90
+ // No silent empty-list fallback and no hardcoded fallback entry in the
91
+ // wizard: editor and server ship from ONE repo, so an unreachable or
92
+ // failing `/templates` is a real defect, not version skew. Surface it.
93
+ const res = await fetch(`${BASE}/templates`);
94
+ const data = await editorServerJson<{ templates: TemplateInfo[] }>(
95
+ res,
96
+ `GET ${BASE}/templates failed`,
97
+ );
98
+ return data.templates;
99
+ }