@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,595 @@
1
+ import {
2
+ faArrowDown,
3
+ type faArrowsUpDownLeftRight,
4
+ faBullseye,
5
+ faCaretDown,
6
+ faCheck,
7
+ faCircleDot,
8
+ faCrosshairs,
9
+ faCube,
10
+ faGlobe,
11
+ faMagnet,
12
+ } from '@fortawesome/free-solid-svg-icons';
13
+ import type { StageTransformDoor, StageTransformKind } from '@volter/editor-sdk/contributions';
14
+ import {
15
+ AnchoredMenu,
16
+ Button,
17
+ Checkbox,
18
+ EditorIcon,
19
+ EditorPopover,
20
+ EditorToolbar,
21
+ editorIcons,
22
+ FloatingToolbar,
23
+ IconButton,
24
+ Inline,
25
+ Keycap,
26
+ MenuItem,
27
+ SplitButtonGroup,
28
+ Stack,
29
+ Text,
30
+ TextInput,
31
+ Tooltip,
32
+ } from '@volter/editor-sdk/widgets';
33
+ import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
34
+ import { useEditorStore } from '../editor-runtime';
35
+ import type { EditorShellStore, GizmoAnchor, PivotMode } from '../editor-shell-store';
36
+ import {
37
+ activeEditorKeymap,
38
+ type EditorKeyActionId,
39
+ shortcutFor,
40
+ subscribeEditorKeymap,
41
+ } from '../keymap-presets';
42
+ import { requestTransformMode } from '../transform-mode-request';
43
+
44
+ /** WHETHER IT IS LIT AND WHAT IT ARMS ARE THE STAGE'S ANSWER, not this
45
+ * button's: the gizmo arm reads `store.transformMode`, a modal door reads its
46
+ * own `armed()` (see `stageTransformDriver` in `stage-context.ts`). */
47
+ function ModeButton({
48
+ active,
49
+ onArm,
50
+ faIcon,
51
+ action,
52
+ label,
53
+ }: {
54
+ active: boolean;
55
+ onArm: () => void;
56
+ faIcon: typeof faArrowsUpDownLeftRight;
57
+ /** The LOGICAL action — its printed key comes from the active keymap. */
58
+ action: EditorKeyActionId;
59
+ label: string;
60
+ }) {
61
+ return (
62
+ <Tooltip text={label} hotkey={shortcutFor(action)}>
63
+ <IconButton
64
+ aria-label={label}
65
+ aria-pressed={active}
66
+ shape="segment"
67
+ size="comfortable"
68
+ onClick={onArm}
69
+ >
70
+ <EditorIcon icon={faIcon} size="md" />
71
+ </IconButton>
72
+ </Tooltip>
73
+ );
74
+ }
75
+
76
+ function SnapButton({
77
+ store,
78
+ dimensions = '3d',
79
+ size = 'comfortable',
80
+ variant = 'ghost',
81
+ }: {
82
+ store: EditorShellStore;
83
+ dimensions?: '2d' | '3d';
84
+ size?: 'compact' | 'default' | 'comfortable';
85
+ variant?: 'ghost' | 'secondary';
86
+ }) {
87
+ const [popoverOpen, setPopoverOpen] = useState(false);
88
+ const ref = useRef<HTMLDivElement>(null);
89
+
90
+ useEffect(() => {
91
+ if (!popoverOpen) return;
92
+ const handler = (event: MouseEvent) => {
93
+ if (ref.current && !ref.current.contains(event.target as Node)) setPopoverOpen(false);
94
+ };
95
+ document.addEventListener('mousedown', handler);
96
+ return () => document.removeEventListener('mousedown', handler);
97
+ }, [popoverOpen]);
98
+
99
+ return (
100
+ <div ref={ref} className="vgai-viewport-popover-anchor">
101
+ <SplitButtonGroup>
102
+ <Tooltip text="Toggle Snap" hotkey={shortcutFor('viewport.toggleSnap')}>
103
+ <IconButton
104
+ aria-label="Toggle snap"
105
+ aria-pressed={store.snapEnabled}
106
+ variant={variant}
107
+ size={size}
108
+ onClick={() => store.toggleSnap()}
109
+ >
110
+ <EditorIcon icon={faMagnet} size="md" />
111
+ </IconButton>
112
+ </Tooltip>
113
+ <Tooltip text="Snap Settings">
114
+ <IconButton
115
+ aria-label="Snap settings"
116
+ // A trigger that opens an anchored SETTINGS popover is a menu
117
+ // button, and `theme.css` reads that off the ARIA rather than a
118
+ // marker attribute — the same honest `dialog` the `Studio v`
119
+ // trigger declares. Blender's snap group is exactly this two-tone
120
+ // split: the magnet half in the pushbutton colour, this half in
121
+ // the menu well (measured native 2x `modeling.png` y=62, the
122
+ // toggle x 1411..1445 at #535353 and the dropdown x 1448..1507 at
123
+ // #272727, one 1 CSS px #3c3c3c divider between them).
124
+ aria-haspopup="dialog"
125
+ aria-expanded={popoverOpen}
126
+ variant={variant}
127
+ size={size}
128
+ onClick={() => setPopoverOpen(!popoverOpen)}
129
+ >
130
+ <EditorIcon icon={faCaretDown} size="xs" />
131
+ </IconButton>
132
+ </Tooltip>
133
+ </SplitButtonGroup>
134
+ {popoverOpen && (
135
+ <EditorPopover className="vgai-snap-popover">
136
+ <Stack gap={2}>
137
+ <Text variant="caption" tone="muted">
138
+ Translate
139
+ </Text>
140
+ <TextInput
141
+ type="number"
142
+ value={store.snapValues.translate}
143
+ step={0.25}
144
+ min={0.01}
145
+ onChange={(event) =>
146
+ store.setSnapValues({ translate: Number(event.target.value) || 1 })
147
+ }
148
+ />
149
+ <Text variant="caption" tone="muted">
150
+ Rotate (deg)
151
+ </Text>
152
+ <TextInput
153
+ type="number"
154
+ value={store.snapValues.rotate}
155
+ step={5}
156
+ min={1}
157
+ onChange={(event) =>
158
+ store.setSnapValues({ rotate: Number(event.target.value) || 15 })
159
+ }
160
+ />
161
+ <Text variant="caption" tone="muted">
162
+ Scale
163
+ </Text>
164
+ <TextInput
165
+ type="number"
166
+ value={store.snapValues.scale}
167
+ step={0.05}
168
+ min={0.01}
169
+ onChange={(event) =>
170
+ store.setSnapValues({ scale: Number(event.target.value) || 0.25 })
171
+ }
172
+ />
173
+ {dimensions === '3d' && (
174
+ <>
175
+ <Inline gap={2} align="center" onClick={() => store.toggleSnapToSurface()}>
176
+ <Checkbox checked={store.snapToSurface} readOnly />
177
+ <Text>Snap to Surface</Text>
178
+ </Inline>
179
+ <Text variant="caption" tone="dim">
180
+ Hold <Keycap>Ctrl</Keycap> while dragging to snap once ·{' '}
181
+ <Keycap>{shortcutFor('viewport.toggleSnap')}</Keycap> toggles
182
+ </Text>
183
+ <Text variant="caption" tone="dim">
184
+ Hold <Keycap>{shortcutFor('viewport.vertexSnapHold')}</Keycap> during translate
185
+ for vertex snap
186
+ </Text>
187
+ </>
188
+ )}
189
+ </Stack>
190
+ </EditorPopover>
191
+ )}
192
+ </div>
193
+ );
194
+ }
195
+
196
+ const pivotLabels: Record<PivotMode, string> = {
197
+ 'active-element': 'Active Element',
198
+ 'median-point': 'Median Point',
199
+ 'individual-origins': 'Individual Origins',
200
+ };
201
+
202
+ function PivotButton({ store }: { store: EditorShellStore }) {
203
+ const modes: PivotMode[] = ['active-element', 'median-point', 'individual-origins'];
204
+ const label = `Pivot: ${pivotLabels[store.pivotMode]}`;
205
+ return (
206
+ <Tooltip text={label} hotkey={shortcutFor('viewport.cyclePivot')}>
207
+ <IconButton
208
+ aria-label={label}
209
+ aria-pressed={store.pivotMode !== 'active-element'}
210
+ variant="secondary"
211
+ onClick={() => {
212
+ const index = modes.indexOf(store.pivotMode);
213
+ store.setPivotMode(modes[(index + 1) % modes.length]!);
214
+ }}
215
+ >
216
+ <EditorIcon icon={faCrosshairs} size="md" />
217
+ </IconButton>
218
+ </Tooltip>
219
+ );
220
+ }
221
+
222
+ const anchorLabels: Record<GizmoAnchor, string> = {
223
+ auto: 'Auto',
224
+ pivot: 'Pivot',
225
+ center: 'Center',
226
+ };
227
+
228
+ /**
229
+ * WHERE the gizmo is drawn — the standard DCC pivot/centre affordance, cycled
230
+ * the way its `PivotButton` neighbour cycles its own three states.
231
+ *
232
+ * `Auto` leads because the right answer is a property of the SUBJECT: an
233
+ * ordinary node's pivot already sits in its content and nothing moves, while a
234
+ * world-anchored instanced system's sits at (0,0,0) with everything visible
235
+ * somewhere else (`instanced-presentation.ts`). The two explicit states are the
236
+ * override, in both directions.
237
+ */
238
+ function AnchorButton({ store }: { store: EditorShellStore }) {
239
+ const modes: GizmoAnchor[] = ['auto', 'pivot', 'center'];
240
+ const label = `Anchor: ${anchorLabels[store.gizmoAnchor]}`;
241
+ return (
242
+ <Tooltip text={label}>
243
+ <IconButton
244
+ aria-label={label}
245
+ aria-pressed={store.gizmoAnchor !== 'auto'}
246
+ variant="secondary"
247
+ onClick={() => {
248
+ const index = modes.indexOf(store.gizmoAnchor);
249
+ store.setGizmoAnchor(modes[(index + 1) % modes.length]!);
250
+ }}
251
+ >
252
+ <EditorIcon icon={store.gizmoAnchor === 'center' ? faCircleDot : faBullseye} size="md" />
253
+ </IconButton>
254
+ </Tooltip>
255
+ );
256
+ }
257
+
258
+ function TransformOptionsButton({ store }: { store: EditorShellStore }) {
259
+ const [open, setOpen] = useState(false);
260
+ const ref = useRef<HTMLDivElement>(null);
261
+ useEffect(() => {
262
+ if (!open) return;
263
+ const close = (event: MouseEvent) => {
264
+ if (!ref.current?.contains(event.target as Node)) setOpen(false);
265
+ };
266
+ document.addEventListener('mousedown', close);
267
+ return () => document.removeEventListener('mousedown', close);
268
+ }, [open]);
269
+ return (
270
+ <div ref={ref} className="vgai-viewport-popover-anchor">
271
+ <Tooltip text="Transform options">
272
+ <IconButton
273
+ aria-label="Transform options"
274
+ // Same reading as the snap group's dropdown half: an anchored
275
+ // settings popover is a menu button, and this is where Blender's
276
+ // proportional-editing dropdown sits in the row.
277
+ aria-haspopup="dialog"
278
+ aria-expanded={open}
279
+ variant="secondary"
280
+ onClick={() => setOpen((value) => !value)}
281
+ >
282
+ <EditorIcon icon={faArrowDown} size="md" />
283
+ </IconButton>
284
+ </Tooltip>
285
+ {open ? (
286
+ <EditorPopover style={{ minWidth: 240 }}>
287
+ <Stack gap={3}>
288
+ <Button
289
+ size="compact"
290
+ variant="ghost"
291
+ onClick={() => {
292
+ store.snapSelectionToFloor();
293
+ setOpen(false);
294
+ }}
295
+ >
296
+ Snap Selection to Floor <Keycap>{shortcutFor('viewport.snapToFloor')}</Keycap>
297
+ </Button>
298
+ <Inline
299
+ gap={2}
300
+ align="center"
301
+ onClick={() => store.togglePreserveChildrenTransform()}
302
+ style={{ cursor: 'pointer' }}
303
+ >
304
+ <Checkbox checked={store.preserveChildrenTransform} readOnly />
305
+ <Text>Preserve Children Transform</Text>
306
+ </Inline>
307
+ <Text variant="caption" tone="dim">
308
+ Keep source-writable children fixed in world space while their parent moves.
309
+ </Text>
310
+ </Stack>
311
+ </EditorPopover>
312
+ ) : null}
313
+ </div>
314
+ );
315
+ }
316
+
317
+ /**
318
+ * THE TRANSFORM ORIENTATION control, transcribed from the frame rather than
319
+ * inferred: Blender's is a LABELLED DROPDOWN, not a cycling toggle. Measured on
320
+ * the native 2x `modeling.png` at row y=70 — the well runs x 1170..1323 (a
321
+ * 1 px #3c3c3c border at each end, #272727 fill between), i.e. 77 CSS px wide,
322
+ * because it carries an orientation glyph, the word `Global`, and a chevron at
323
+ * x 1304..1316 (13x8 device px, 6.5x4 CSS, peak 216). Ours was a 20 px
324
+ * icon-only button that cycled on click, which is also why the widget-colour
325
+ * rule painted it the #535353 pushbutton where the frame shows the menu well:
326
+ * the colour was agreeing with what the control DID.
327
+ *
328
+ * The STORE's vocabulary is unchanged and stays three.js's (`world`/`local`);
329
+ * only the printed word is the reference's, because `Global` is what this
330
+ * control is called in the frame this skew is transcribing.
331
+ */
332
+ function TransformOrientationButton({ store }: { store: EditorShellStore }) {
333
+ const [open, setOpen] = useState(false);
334
+ const triggerRef = useRef<HTMLButtonElement>(null);
335
+ const label = store.transformSpace === 'world' ? 'Global' : 'Local';
336
+ return (
337
+ <div className="vgai-viewport-popover-anchor">
338
+ <Tooltip text={`Transform orientation: ${label}`}>
339
+ <Button
340
+ ref={triggerRef}
341
+ type="button"
342
+ size="compact"
343
+ variant="secondary"
344
+ aria-label={`Transform orientation: ${label}`}
345
+ aria-haspopup="menu"
346
+ aria-expanded={open}
347
+ onClick={() => setOpen((value) => !value)}
348
+ className="vgai-transform-orientation-trigger"
349
+ >
350
+ <EditorIcon icon={store.transformSpace === 'world' ? faGlobe : faCube} size="sm" />
351
+ <span>{label}</span>
352
+ <EditorIcon icon={faCaretDown} size="xs" />
353
+ </Button>
354
+ </Tooltip>
355
+ {open && (
356
+ <AnchoredMenu
357
+ anchorRef={triggerRef}
358
+ align="start"
359
+ clamp
360
+ aria-label="Transform orientation"
361
+ onDismiss={() => setOpen(false)}
362
+ >
363
+ {(['world', 'local'] as const).map((space) => (
364
+ <MenuItem
365
+ key={space}
366
+ role="menuitemradio"
367
+ aria-checked={store.transformSpace === space}
368
+ onSelect={() => {
369
+ store.setTransformSpace(space);
370
+ setOpen(false);
371
+ }}
372
+ >
373
+ <span className="vgai-menu-check">
374
+ {store.transformSpace === space && <EditorIcon icon={faCheck} size="xs" />}
375
+ </span>
376
+ {space === 'world' ? 'Global' : 'Local'}
377
+ </MenuItem>
378
+ ))}
379
+ </AnchoredMenu>
380
+ )}
381
+ </div>
382
+ );
383
+ }
384
+
385
+ /**
386
+ * THE VIEWPORT HEADER'S TRANSFORM CONTROLS — orientation, pivot, snap and the
387
+ * transform options, drawn in the document's header beside the host's 3D
388
+ * controls (`DocumentHeaderStrip`).
389
+ *
390
+ * WHY HERE AND NOT ON THE SHELF: a control is placed by the panel that owns its
391
+ * job in the reference. In Blender's 3D viewport these four are HEADER
392
+ * controls — transform orientation, transform pivot point, snapping with its
393
+ * dropdown, proportional editing — and the tool shelf (T) holds tools only.
394
+ * They rode the `ToolStrip` here until 2026-09-18, and the magnet is what
395
+ * showed it: a horizontal `SplitButtonGroup` inside a rail one tool wide spent
396
+ * two boxes and hung a half-width caret off the column.
397
+ *
398
+ * THE GROUPING IS TRANSCRIBED, measured on the native 2x `modeling.png`
399
+ * (row y=62, x in device px): Blender lays four separate WELLS with 12 device
400
+ * px (6 CSS px) of bare header between them — orientation x 1171..1322 (76 CSS
401
+ * px, it carries the "Global" label), pivot x 1335..1396 (31), snap
402
+ * x 1409..1510 (51), proportional editing x 1523..1624 (51). The last two are
403
+ * SPLIT: a toggle segment in the pushbutton colour (#535353) then a one-pixel
404
+ * #3c3c3c divider then an icon+caret dropdown in the menu-well colour
405
+ * (#272727) — exactly the `SplitButtonGroup` shape the magnet already had, in
406
+ * the row where it lays out. Each well is 40 device px tall (20 CSS px, the
407
+ * density's control height) inside a 54-device-px header band.
408
+ *
409
+ * Each control is `secondary`, so the estate's widget-colour rule paints it:
410
+ * a toggle takes the pushbutton class and a popover trigger the menu well,
411
+ * read off the trigger's own ARIA (`theme.css`, "A MENU BUTTON"). They drew as
412
+ * ghost icons floating on the header band before that — measured beside the
413
+ * frame at 4x, every one of Blender's carries a well.
414
+ *
415
+ * Three readings where ours differs from the frame, kept as they are because
416
+ * this unit moves placement and not shape: Blender's orientation is a labelled
417
+ * dropdown (`Global v`) where ours cycles world/local on click — so ours takes
418
+ * the pushbutton #535353 where the frame shows the #272727 menu well, which is
419
+ * the colour rule agreeing with what the control DOES; its pivot is one
420
+ * dropdown where we carry two cycling toggles — pivot MODE and gizmo ANCHOR,
421
+ * sharing one well because they are one job (where the gizmo sits), which is
422
+ * how Blender groups them; and our toggles are 20x20 against the frame's 31
423
+ * for pivot, because a cycling toggle carries no caret.
424
+ */
425
+ export function TransformHeaderControls({ store: stage }: { store?: EditorShellStore } = {}) {
426
+ // THE STAGE'S OWN STORE, when the caller knows it. Every stage owns an
427
+ // `EditorShellStore` (`stage-store-registry.ts`) and these four configure
428
+ // the gizmo in THAT stage's viewport, so writing the shell's from over a
429
+ // document stage set a value nothing on screen reads — MEASURED 2026-09-19
430
+ // on a prefab story: with the shell at `rotate`, the story's stage kept
431
+ // drawing the default COMBINED gizmo, and two captures a mode apart were
432
+ // byte-identical. The world root's stage runs on the shell store itself, so
433
+ // the Scene document is unchanged either way.
434
+ const shell = useEditorStore();
435
+ const store = stage ?? shell;
436
+ useSyncExternalStore(store.subscribe, store.getShellSnapshot ?? store.getSnapshot);
437
+ useSyncExternalStore(subscribeEditorKeymap, activeEditorKeymap, activeEditorKeymap);
438
+ return (
439
+ <EditorToolbar
440
+ compact
441
+ label="Transform controls"
442
+ data-testid="transform-header-controls"
443
+ className="vgai-transform-header-controls"
444
+ >
445
+ <TransformOrientationButton store={store} />
446
+ <SplitButtonGroup>
447
+ <PivotButton store={store} />
448
+ <AnchorButton store={store} />
449
+ </SplitButtonGroup>
450
+ <SnapButton store={store} size="default" variant="secondary" />
451
+ <TransformOptionsButton store={store} />
452
+ </EditorToolbar>
453
+ );
454
+ }
455
+
456
+ /**
457
+ * THE TOOL SHELF'S STRIP — tools, and nothing else (Blender's T shelf). The
458
+ * four header controls that used to trail it live in
459
+ * {@link TransformHeaderControls} now; the 2D canvas surface keeps its snap
460
+ * control inline because this strip lays out as a ROW over that stage (see
461
+ * `.vgai-viewport-toolbar-left` in `workspace-dock.css`) and that surface has
462
+ * no Blender analogue to place it against.
463
+ *
464
+ * THESE FOUR ARE BLENDER'S OWN SECOND TOOLBAR GROUP, and the order is its
465
+ * order. Measured 2026-09-19 on `modeling-edit-none.png`: the Edit Mode
466
+ * toolbar's 21 buttons run in five groups of 2 / 4 / 2 / 1 / 12, and group 2
467
+ * is exactly Move, Rotate, Scale, Transform — the same four verbs this strip
468
+ * has always carried, under Font Awesome drawings and with the combined tool
469
+ * FIRST. So the answer to "do the host's navigation buttons belong at the top
470
+ * of a Blender toolbar at all" is yes and they were already right; what was
471
+ * wrong was the order (Transform leads in Blender's list only as the LAST
472
+ * member, the all-handles fallback after the three single-channel tools) and
473
+ * two of the glyphs (`editorIcons.tool`'s docblock says which and why).
474
+ * BLENDER'S GROUP 1 IS SELECT BOX AND THE 3D CURSOR, and as of 2026-09-21 the
475
+ * FIRST of the two is drawn above them while the second is still not. The
476
+ * earlier note here said neither was, and its reason was right at the time:
477
+ * neither had anything behind it once the Edit Mesh document was deleted (the
478
+ * 21-row table that said what each of the twenty-one does is in git,
479
+ * `packages/mesh/contributions/mesh-edit-document.tsx` before 2026-09-19).
480
+ * Select Box has something behind it NOW — `TransformMode`'s `'select'`, the
481
+ * state in which no transform gizmo is drawn at all, which is what Blender's
482
+ * viewport opens in (`gizmo-select-box.png`; the look states it through
483
+ * `workspace-regions.ts`'s `shelfTool`). The 3D cursor still has nothing
484
+ * behind it and is still not drawn; adding the button before the cursor exists
485
+ * would be exactly the inert control the paragraph below removes.
486
+ *
487
+ * WHAT THEY DRIVE IS THE STAGE'S ANSWER, in two parts.
488
+ *
489
+ * `store` — WHICH STAGE'S GIZMO. Every stage owns an `EditorShellStore`
490
+ * (`stage-store-registry.ts`), and these four write `transformMode`, which
491
+ * that stage's `EditorViewport` reads. Writing the SHELL's from over a
492
+ * document stage set a value nothing on screen read: MEASURED 2026-09-19 on
493
+ * a prefab story with its subject selected, the shell store at `rotate`, the
494
+ * stage still drawing the default COMBINED gizmo, and two `capture-active-
495
+ * document` frames a mode apart BYTE-IDENTICAL. That, not a missing gizmo,
496
+ * is why these four were inert over a document stage. The world root's stage
497
+ * runs on the shell store itself, so the Scene document is unchanged.
498
+ *
499
+ * `door` — a stage that transforms MODALLY instead (a Model document's
500
+ * `G`/`R`/`S`, `registerStageTransform` in `@volter/editor-sdk/contributions`,
501
+ * whose note carries that measurement). Then the three single-channel tools
502
+ * arm it and the all-handles tool is NOT DRAWN: Blender's fourth is a gizmo
503
+ * and a modal transform has no twin for it, so drawing it would be the inert
504
+ * control this seam exists to remove. `stageTransformDriver`
505
+ * (`stage-context.ts`) is what chooses between the two.
506
+ */
507
+ const NO_DOOR_SUBSCRIBE = () => () => {};
508
+ const NO_DOOR_ARMED = () => null;
509
+
510
+ export function ToolStrip({
511
+ dimensions = '3d',
512
+ door,
513
+ store: stage,
514
+ }: {
515
+ dimensions?: '2d' | '3d';
516
+ door?: StageTransformDoor;
517
+ store?: EditorShellStore;
518
+ } = {}) {
519
+ const shell = useEditorStore();
520
+ const store = stage ?? shell;
521
+ useSyncExternalStore(store.subscribe, store.getShellSnapshot ?? store.getSnapshot);
522
+ // Every hint below is rendered from the active keymap; a live switch must
523
+ // repaint the strip rather than leave it advertising the other table.
524
+ useSyncExternalStore(subscribeEditorKeymap, activeEditorKeymap, activeEditorKeymap);
525
+ // A modal transform's lit state is the DOOR's, and it changes without the
526
+ // shell store moving at all — the same `useSyncExternalStore` pair every
527
+ // out-of-tree panel uses, with the mesh document's own null-session shape
528
+ // for the gizmo arm (hooks cannot be conditional).
529
+ const armed = useSyncExternalStore(
530
+ door?.subscribe ?? NO_DOOR_SUBSCRIBE,
531
+ door?.armed ?? NO_DOOR_ARMED,
532
+ door?.armed ?? NO_DOOR_ARMED,
533
+ );
534
+ const single = [
535
+ {
536
+ mode: 'translate',
537
+ faIcon: editorIcons.tool.move,
538
+ action: 'transform.translate',
539
+ label: 'Move',
540
+ },
541
+ {
542
+ mode: 'rotate',
543
+ faIcon: editorIcons.tool.rotate,
544
+ action: 'transform.rotate',
545
+ label: 'Rotate',
546
+ },
547
+ { mode: 'scale', faIcon: editorIcons.tool.scale, action: 'transform.scale', label: 'Scale' },
548
+ ] as const satisfies readonly {
549
+ mode: StageTransformKind;
550
+ faIcon: typeof faArrowsUpDownLeftRight;
551
+ action: EditorKeyActionId;
552
+ label: string;
553
+ }[];
554
+ return (
555
+ <FloatingToolbar
556
+ label="Transform tools"
557
+ data-testid={dimensions === '2d' ? 'canvas-2d-toolstrip' : 'threejs-toolstrip'}
558
+ className="vgai-viewport-toolbar vgai-viewport-toolbar-left"
559
+ >
560
+ {/* SELECT BOX, first — Blender's own group 1 (see the docblock). It is
561
+ not offered over a MODAL door: `door.begin` takes a transform kind
562
+ and a modal transform has no "arm nothing" member, so the button
563
+ would have nothing to call. */}
564
+ {door ? null : (
565
+ <ModeButton
566
+ faIcon={editorIcons.tool.select}
567
+ action="transform.select"
568
+ label="Select"
569
+ active={store.transformMode === 'select'}
570
+ onArm={() => requestTransformMode(store, 'select')}
571
+ />
572
+ )}
573
+ {single.map((tool) => (
574
+ <ModeButton
575
+ key={tool.mode}
576
+ faIcon={tool.faIcon}
577
+ action={tool.action}
578
+ label={tool.label}
579
+ active={door ? armed === tool.mode : store.transformMode === tool.mode}
580
+ onArm={() => (door ? door.begin(tool.mode) : requestTransformMode(store, tool.mode))}
581
+ />
582
+ ))}
583
+ {door ? null : (
584
+ <ModeButton
585
+ faIcon={editorIcons.tool.transform}
586
+ action="transform.combined"
587
+ label="Transform (all handles)"
588
+ active={store.transformMode === 'combined'}
589
+ onArm={() => requestTransformMode(store, 'combined')}
590
+ />
591
+ )}
592
+ {dimensions === '2d' ? <SnapButton store={store} dimensions="2d" /> : null}
593
+ </FloatingToolbar>
594
+ );
595
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Renders the editor's transient hint (see `../transient-hint.ts` for the
3
+ * publisher and the rationale). Mounted once, near the bottom of the viewport;
4
+ * absent from the DOM entirely when there is nothing to say.
5
+ *
6
+ * `role="status"` + `aria-live="polite"` so a refusal is announced, not just
7
+ * drawn — this exists BECAUSE the refusal used to be silent.
8
+ */
9
+
10
+ import { space, themeVars, zIndex } from '@volter/editor-sdk/widgets';
11
+ import { useSyncExternalStore } from 'react';
12
+ import { subscribeTransientHint, transientHint } from '../transient-hint';
13
+
14
+ export function TransientHintOverlay() {
15
+ const hint = useSyncExternalStore(subscribeTransientHint, transientHint, transientHint);
16
+ if (!hint) return null;
17
+ return (
18
+ <div
19
+ key={hint.id}
20
+ role="status"
21
+ aria-live="polite"
22
+ data-testid="transient-hint"
23
+ style={{
24
+ position: 'absolute',
25
+ left: '50%',
26
+ bottom: space[6],
27
+ transform: 'translateX(-50%)',
28
+ maxWidth: 'min(440px, 80%)',
29
+ padding: `${space[3]}px ${space[5]}px`,
30
+ borderRadius: themeVars.shape.medium,
31
+ border: `1px solid ${themeVars.boundary.strong}`,
32
+ background: themeVars.surface.overlay,
33
+ color: themeVars.content.primary,
34
+ fontSize: 'var(--vgai-font-base)',
35
+ lineHeight: 1.4,
36
+ textAlign: 'center',
37
+ pointerEvents: 'none',
38
+ zIndex: zIndex.toast,
39
+ }}
40
+ >
41
+ {hint.message}
42
+ </div>
43
+ );
44
+ }