@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,107 @@
1
+ /** Shell overlays for document stages: selection controls, camera readout,
2
+ * hints and statistics. Package documents supply their own chrome. */
3
+
4
+ import { useSyncExternalStore } from 'react';
5
+ import { activeAuthoringVersion, subscribeActiveAuthoring } from '../authoring/active-adapter';
6
+ import {
7
+ object3DDocumentSessionsVersion,
8
+ subscribeObject3DDocumentSessions,
9
+ } from '../authoring/object3d-document-session-registry';
10
+ import type { EditorShellStore } from '../editor-shell-store';
11
+ import type { EditorViewport } from '../editor-viewport';
12
+ import { documentStageContext, type StageChrome, threeSelectionToolsApply } from '../stage-context';
13
+ import {
14
+ subscribeWorkspaceDocuments,
15
+ workspaceDocumentRegistryVersion,
16
+ } from '../workspace-document-registry';
17
+ import { CameraInfo } from './CameraInfo';
18
+ import { StatsOverlay } from './StatsOverlay';
19
+ import { TransientHintOverlay } from './TransientHint';
20
+ import { ViewportControlsHint } from './ViewportControlsHint';
21
+ import { ViewportOverlay } from './ViewportOverlay';
22
+
23
+ /** What the HOST hands over about the stage itself — its own store, the
24
+ * viewport the hotkeys drive and the canvas that claims their scope. Null
25
+ * until the stage has finished building. */
26
+ export interface StageHandle {
27
+ readonly store: EditorShellStore;
28
+ readonly viewport: EditorViewport;
29
+ readonly canvas: HTMLCanvasElement;
30
+ }
31
+
32
+ export interface StageOverlaySetProps {
33
+ readonly store: EditorShellStore;
34
+ readonly documentId: string;
35
+ /** This stage's own handle; `null` while it is still building. */
36
+ readonly stage: StageHandle | null;
37
+ /** Whether this stage's document is the ACTIVE centre tab. */
38
+ readonly active: boolean;
39
+ /** The host's own answer to `StageContext.chrome`. */
40
+ readonly chrome: StageChrome;
41
+
42
+ }
43
+
44
+ export function StageOverlaySet({
45
+ store,
46
+ documentId,
47
+ stage,
48
+ active,
49
+ chrome,
50
+ }: StageOverlaySetProps) {
51
+ /** THIS stage's own store — the shell's until the stage has finished
52
+ * building, which is the same store every overlay read before unit 4. */
53
+ const stageStore = stage?.store ?? store;
54
+ useSyncExternalStore(store.subscribe, store.getShellSnapshot ?? store.getSnapshot);
55
+ // The stage's own state (its grid, helpers, stats, tool mode) lives on ITS
56
+ // store, so the overlays that read it subscribe there too.
57
+ useSyncExternalStore(stageStore.subscribe, stageStore.getShellSnapshot ?? stageStore.getSnapshot);
58
+ useSyncExternalStore(subscribeActiveAuthoring, activeAuthoringVersion);
59
+ useSyncExternalStore(subscribeObject3DDocumentSessions, object3DDocumentSessionsVersion);
60
+ useSyncExternalStore(subscribeWorkspaceDocuments, workspaceDocumentRegistryVersion);
61
+ // THIS stage's context — not the focused one. A capability is present where
62
+ // its condition holds, and the condition is asked of the stage that would
63
+ // draw it (ARCHITECTURE-CORE §One stage).
64
+ const ctx = documentStageContext(store, documentId, chrome);
65
+ /** Whether the selection tools draw here — and that is the WHOLE condition:
66
+ * they read THIS stage's own store (`stage.store`, the one the shared
67
+ * panels reach through `focusedStageStore()`), so a prefab's grid button
68
+ * toggles the prefab's grid and its readout reports the camera its reader
69
+ * is looking through. The controls hint is the other half of this one
70
+ * decision, not a second reading of the selection. */
71
+ const showsSelectionTools = threeSelectionToolsApply(ctx);
72
+ return (
73
+ <>
74
+ {/* THE STAGE'S OWN KEYBOARD is no longer mounted here: this module is
75
+ reached only by a stage that has the shell above it, and a
76
+ package-contributed document (the Model document) has none — so it
77
+ answered no stage key at all. It is `StageHost.tsx`'s now, beside
78
+ the stage handle, under the same activation condition
79
+ (`stage-keyboard.tsx` carries the measurement). */}
80
+ {showsSelectionTools ? (
81
+ <>
82
+ <ViewportOverlay store={stageStore} documentId={documentId} />
83
+ <CameraInfo />
84
+ </>
85
+ ) : null}
86
+ {/* The hint also shows WHILE the world is still mounting: a new user
87
+ reads the screen during those boot seconds, and two human passes in
88
+ a row looked for the camera controls exactly then and reported them
89
+ missing (runhuman passes 15 and 17, 2026-08-28/29). It names the
90
+ KEYMAP's own camera verbs and no store's state, so EVERY stage
91
+ carries it. */}
92
+ {!showsSelectionTools && ctx.surface === 'three' ? (
93
+ <ViewportControlsHint />
94
+ ) : null}
95
+ {ctx.surface === 'three' && stageStore.showStats && <StatsOverlay />}
96
+ {/* H2 — the ONE transient hint channel. Lives here because a refused
97
+ transform is a viewport gesture; the overlay is absent from the DOM
98
+ entirely until something has a reason to say. ONE channel means one
99
+ mount — the ACTIVE stage's — so a hint never draws twice. */}
100
+ {active ? <TransientHintOverlay /> : null}
101
+ {/* W4 (inventory row V9): the scene document mounts NO network overlay.
102
+ Compact connection state lives in the status bar
103
+ (`status-contributions.tsx`); the detailed surface is the `network`
104
+ workspace utility (`NetworkInspectorPanel`), revealed from there. */}
105
+ </>
106
+ );
107
+ }
@@ -0,0 +1,478 @@
1
+ /**
2
+ * THE OTHER PARTICIPANTS, ON A STAGE — the spatial half of collaboration
3
+ * presence: what THIS stage publishes about the reader's own camera and
4
+ * gestures, and the camera frusta, selection boxes and pointer rays it paints
5
+ * for everyone else (WORK.md §Presence and the substrate, presence unit 4).
6
+ *
7
+ * It was the scene panel's, so only the world root had it. Under
8
+ * ARCHITECTURE-CORE §One stage it is a CAPABILITY with a condition — a stage
9
+ * painting a three surface — so every 3D document mounts it and a prefab
10
+ * story shows the same markers the Scene does.
11
+ *
12
+ * WHICH STAGE A PARTICIPANT IS ON. Presence is ONE record per participant
13
+ * (`collaboration-presence.ts`), and its `document` field is written by the
14
+ * shell for the ACTIVE workspace document (`DefaultEditorLayout.tsx`). So a
15
+ * stage publishes its camera only while its own document is the active one —
16
+ * otherwise several stages would overwrite each other's pose in the single
17
+ * record — and paints a participant only on the stage whose id matches that
18
+ * participant's `presence.document`. Measured against the spec's "publish it
19
+ * from the host with the stage's documentId": the presence record has ONE
20
+ * `document` field and the shell already owns it, so the stage owns the
21
+ * CONDITION on writing, not a second writer of that field.
22
+ */
23
+
24
+ import type { CollaborationParticipant } from '@volter/editor-sdk/session/collaboration-types';
25
+ import { EDITOR_THEME_CLASS, graphiteDarkEditorTheme } from '@volter/editor-sdk/widgets';
26
+ import { contentWorldBounds } from '@volter/editor-threejs/viewport/content-bounds';
27
+ import * as THREE from 'three';
28
+ import { collaborationSnapshot } from '../collaboration-client';
29
+ import { reportCollaborationPresence } from '../collaboration-presence';
30
+ import { EDITOR_PARTICIPANT_ID } from '../editor-presence';
31
+ import type { EditorShellStore } from '../editor-shell-store';
32
+ import type { EditorViewport } from '../editor-viewport';
33
+ import { activeWorkspaceDocumentId } from '../workspace-document-registry';
34
+
35
+ interface RemoteCameraMarker {
36
+ camera: THREE.PerspectiveCamera;
37
+ helper: THREE.CameraHelper;
38
+ label: THREE.Sprite;
39
+ texture: THREE.CanvasTexture;
40
+ signature: string;
41
+ targetPosition: THREE.Vector3;
42
+ targetQuaternion: THREE.Quaternion;
43
+ targetFov: number;
44
+ initialized: boolean;
45
+ }
46
+
47
+ interface RemoteSelectionMarker {
48
+ object: THREE.Object3D;
49
+ box: THREE.Box3;
50
+ helper: THREE.Box3Helper;
51
+ }
52
+
53
+ interface RemoteRayMarker {
54
+ line: THREE.Line;
55
+ positions: THREE.BufferAttribute;
56
+ }
57
+
58
+ /**
59
+ * Remote-camera labels paint into a DETACHED canvas, and a 2D context cannot
60
+ * resolve `var(--vgai-…)` — so the theme's value has to be read off the live
61
+ * theme root before it reaches `fillStyle`. Before a theme is installed (unit
62
+ * environments), fall back to the default theme's own value rather than a raw
63
+ * literal, so the label never depends on a color the theme contract doesn't own.
64
+ */
65
+ function contentOnAccentColor(): string {
66
+ const root = document.querySelector(`.${EDITOR_THEME_CLASS}`);
67
+ const resolved = root
68
+ ? getComputedStyle(root).getPropertyValue('--vgai-content-on-accent').trim()
69
+ : '';
70
+ return resolved || graphiteDarkEditorTheme.color.content.onAccent;
71
+ }
72
+
73
+ function drawRemoteCameraLabel(
74
+ texture: THREE.CanvasTexture,
75
+ participant: CollaborationParticipant,
76
+ ): void {
77
+ const canvas = texture.image as HTMLCanvasElement;
78
+ const context = canvas.getContext('2d');
79
+ if (!context) return;
80
+ context.clearRect(0, 0, canvas.width, canvas.height);
81
+ context.fillStyle = participant.color;
82
+ context.beginPath();
83
+ context.roundRect(2, 2, canvas.width - 4, canvas.height - 4, 16);
84
+ context.fill();
85
+ context.fillStyle = contentOnAccentColor();
86
+ context.font = '600 22px system-ui, sans-serif';
87
+ context.textAlign = 'center';
88
+ context.textBaseline = 'middle';
89
+ const suffix = participant.kind === 'agent' ? ' · AI' : '';
90
+ context.fillText(`${participant.displayName}${suffix}`, canvas.width / 2, canvas.height / 2, 238);
91
+ texture.needsUpdate = true;
92
+ }
93
+
94
+ function createRemoteCameraMarker(participant: CollaborationParticipant): RemoteCameraMarker {
95
+ const camera = new THREE.PerspectiveCamera(50, 1, 0.2, 1.4);
96
+ const helper = new THREE.CameraHelper(camera);
97
+ const color = new THREE.Color(participant.color);
98
+ helper.setColors(color, color, color, color, color);
99
+ helper.name = `Collaboration camera: ${participant.displayName}`;
100
+ helper.userData['editorOnly'] = true;
101
+ const canvas = document.createElement('canvas');
102
+ canvas.width = 256;
103
+ canvas.height = 64;
104
+ const texture = new THREE.CanvasTexture(canvas);
105
+ texture.colorSpace = THREE.SRGBColorSpace;
106
+ const label = new THREE.Sprite(
107
+ new THREE.SpriteMaterial({ map: texture, depthTest: false, transparent: true }),
108
+ );
109
+ label.name = `Collaboration label: ${participant.displayName}`;
110
+ label.userData['editorOnly'] = true;
111
+ label.scale.set(1.8, 0.45, 1);
112
+ label.renderOrder = 10_000;
113
+ drawRemoteCameraLabel(texture, participant);
114
+ return {
115
+ camera,
116
+ helper,
117
+ label,
118
+ texture,
119
+ signature: '',
120
+ targetPosition: new THREE.Vector3(),
121
+ targetQuaternion: new THREE.Quaternion(),
122
+ targetFov: 50,
123
+ initialized: false,
124
+ };
125
+ }
126
+
127
+ function updateRemoteCameraMarker(
128
+ marker: RemoteCameraMarker,
129
+ participant: CollaborationParticipant,
130
+ ): void {
131
+ const pose = participant.presence.camera;
132
+ if (!pose) return;
133
+ marker.targetPosition.set(pose.x, pose.y, pose.z);
134
+ const targetCamera = new THREE.Object3D();
135
+ targetCamera.position.copy(marker.targetPosition);
136
+ targetCamera.lookAt(pose.targetX, pose.targetY, pose.targetZ);
137
+ marker.targetQuaternion.copy(targetCamera.quaternion);
138
+ marker.targetFov = pose.fov;
139
+ if (!marker.initialized) {
140
+ marker.initialized = true;
141
+ marker.camera.position.copy(marker.targetPosition);
142
+ marker.camera.quaternion.copy(marker.targetQuaternion);
143
+ marker.camera.fov = marker.targetFov;
144
+ }
145
+ const signature = `${participant.displayName}|${participant.kind}|${participant.color}|${participant.status}`;
146
+ if (signature !== marker.signature) {
147
+ marker.signature = signature;
148
+ drawRemoteCameraLabel(marker.texture, participant);
149
+ }
150
+ }
151
+
152
+ function animateRemoteCameraMarker(marker: RemoteCameraMarker, dt: number): void {
153
+ const blend = 1 - Math.exp(-12 * Math.max(0, dt));
154
+ marker.camera.position.lerp(marker.targetPosition, blend);
155
+ marker.camera.quaternion.slerp(marker.targetQuaternion, blend);
156
+ marker.camera.fov += (marker.targetFov - marker.camera.fov) * blend;
157
+ marker.camera.updateProjectionMatrix();
158
+ marker.camera.updateMatrixWorld(true);
159
+ marker.helper.update();
160
+ marker.label.position.copy(marker.camera.position);
161
+ marker.label.position.y += 0.55;
162
+ }
163
+
164
+ function disposeRemoteCameraMarker(marker: RemoteCameraMarker): void {
165
+ marker.helper.removeFromParent();
166
+ marker.label.removeFromParent();
167
+ marker.helper.dispose();
168
+ marker.texture.dispose();
169
+ (marker.label.material as THREE.SpriteMaterial).dispose();
170
+ }
171
+
172
+ function createRemoteSelectionMarker(object: THREE.Object3D, color: string): RemoteSelectionMarker {
173
+ const box = contentWorldBounds(object);
174
+ const helper = new THREE.Box3Helper(box, new THREE.Color(color));
175
+ helper.name = `Collaboration selection: ${object.name || object.uuid}`;
176
+ helper.userData['editorOnly'] = true;
177
+ helper.renderOrder = 9_999;
178
+ (helper.material as THREE.LineBasicMaterial).depthTest = false;
179
+ return { object, box, helper };
180
+ }
181
+
182
+ function disposeRemoteSelectionMarker(marker: RemoteSelectionMarker): void {
183
+ marker.helper.removeFromParent();
184
+ marker.helper.geometry.dispose();
185
+ (marker.helper.material as THREE.Material).dispose();
186
+ }
187
+
188
+ function pointerRayGesture(value: Readonly<Record<string, unknown>> | null): {
189
+ origin: THREE.Vector3;
190
+ end: THREE.Vector3;
191
+ } | null {
192
+ if (!value || value['type'] !== 'pointer-ray') return null;
193
+ const keys = [
194
+ 'originX',
195
+ 'originY',
196
+ 'originZ',
197
+ 'directionX',
198
+ 'directionY',
199
+ 'directionZ',
200
+ 'length',
201
+ ] as const;
202
+ if (!keys.every((key) => typeof value[key] === 'number' && Number.isFinite(value[key]))) {
203
+ return null;
204
+ }
205
+ const origin = new THREE.Vector3(
206
+ value['originX'] as number,
207
+ value['originY'] as number,
208
+ value['originZ'] as number,
209
+ );
210
+ const direction = new THREE.Vector3(
211
+ value['directionX'] as number,
212
+ value['directionY'] as number,
213
+ value['directionZ'] as number,
214
+ );
215
+ const length = Math.min(1_000, Math.max(0.1, value['length'] as number));
216
+ if (direction.lengthSq() < 0.000_001) return null;
217
+ return { origin, end: origin.clone().add(direction.normalize().multiplyScalar(length)) };
218
+ }
219
+
220
+ export interface StagePresenceOptions {
221
+ /** The scene the markers are added to — the stage's own drawn scene. */
222
+ readonly scene: THREE.Scene;
223
+ readonly store: EditorShellStore;
224
+ /** The stage's document id: the presence records painted here are the ones
225
+ * whose own `document` is this. */
226
+ readonly documentId: string;
227
+ readonly container: HTMLElement;
228
+ readonly canvas: HTMLCanvasElement;
229
+ readonly viewport: EditorViewport;
230
+ /** The pose the reader is actually looking through, in world space. */
231
+ readonly readVisibleCameraPose: () => {
232
+ readonly position: THREE.Vector3;
233
+ readonly target: THREE.Vector3;
234
+ readonly fov: number;
235
+ };
236
+ }
237
+
238
+ export interface StagePresenceBinding {
239
+ /** Publish the reader's camera now (after a view change the frame loop's
240
+ * pose comparison would otherwise notice a frame late). */
241
+ reportCamera(): void;
242
+ /** Per frame: project new presence sequences and animate the markers. */
243
+ syncMarkers(dtSeconds: number): void;
244
+ dispose(): void;
245
+ }
246
+
247
+ export function bindStagePresenceMarkers(options: StagePresenceOptions): StagePresenceBinding {
248
+ const { scene, store, documentId, container, canvas, viewport, readVisibleCameraPose } = options;
249
+ /** THE WRITE CONDITION: one presence record, one `document` field — a stage
250
+ * that is not the active document does not speak for the reader. */
251
+ const publishes = (): boolean => activeWorkspaceDocumentId() === documentId;
252
+
253
+ const reportCamera = (): void => {
254
+ if (!publishes()) return;
255
+ const pose = readVisibleCameraPose();
256
+ reportCollaborationPresence({
257
+ camera: {
258
+ x: pose.position.x,
259
+ y: pose.position.y,
260
+ z: pose.position.z,
261
+ targetX: pose.target.x,
262
+ targetY: pose.target.y,
263
+ targetZ: pose.target.z,
264
+ fov: pose.fov,
265
+ },
266
+ });
267
+ };
268
+ viewport.orbitControls.addEventListener('change', reportCamera);
269
+
270
+ let transformDragging = false;
271
+ const reportTransformGesture = (event: THREE.Event): void => {
272
+ const dragging = (event as unknown as { value?: unknown }).value === true;
273
+ transformDragging = dragging;
274
+ if (!publishes()) return;
275
+ reportCollaborationPresence({
276
+ gesture: dragging ? { type: 'transform', selection: [...store.selectedEntityIds] } : null,
277
+ });
278
+ };
279
+ viewport.transformControls.addEventListener('dragging-changed', reportTransformGesture);
280
+
281
+ const pointerRaycaster = new THREE.Raycaster();
282
+ const pointerNdc = new THREE.Vector2();
283
+ const reportPointerRay = (event: PointerEvent): void => {
284
+ if (transformDragging || event.buttons !== 0 || !publishes()) return;
285
+ const bounds = canvas.getBoundingClientRect();
286
+ if (bounds.width <= 0 || bounds.height <= 0) return;
287
+ pointerNdc.set(
288
+ ((event.clientX - bounds.left) / bounds.width) * 2 - 1,
289
+ -((event.clientY - bounds.top) / bounds.height) * 2 + 1,
290
+ );
291
+ pointerRaycaster.setFromCamera(pointerNdc, viewport.renderCamera);
292
+ const ray = pointerRaycaster.ray;
293
+ const pose = readVisibleCameraPose();
294
+ reportCollaborationPresence({
295
+ gesture: {
296
+ type: 'pointer-ray',
297
+ originX: ray.origin.x,
298
+ originY: ray.origin.y,
299
+ originZ: ray.origin.z,
300
+ directionX: ray.direction.x,
301
+ directionY: ray.direction.y,
302
+ directionZ: ray.direction.z,
303
+ length: Math.max(2, pose.position.distanceTo(pose.target)),
304
+ },
305
+ });
306
+ };
307
+ const clearPointerRay = (): void => {
308
+ if (!transformDragging && publishes()) reportCollaborationPresence({ gesture: null });
309
+ };
310
+ container.addEventListener('pointermove', reportPointerRay);
311
+ container.addEventListener('pointerleave', clearPointerRay);
312
+ reportCamera();
313
+
314
+ // Remote editors are represented in the scene with their real reported
315
+ // camera frustum and a billboard label. This is spatial presence, not a
316
+ // guessed avatar location: participants without a live camera publish no
317
+ // marker. The collaboration snapshot is already refreshed by the page's
318
+ // presence surface, so the render loop only projects new sequences.
319
+ const remoteCameraMarkers = new Map<string, RemoteCameraMarker>();
320
+ const remoteSelectionMarkers = new Map<string, RemoteSelectionMarker>();
321
+ const remoteRayMarkers = new Map<string, RemoteRayMarker>();
322
+ let remotePresenceSequence = -1;
323
+ const syncRemoteSpatialMarkers = (): void => {
324
+ const snapshot = collaborationSnapshot();
325
+ if (!snapshot || snapshot.sequence === remotePresenceSequence) return;
326
+ remotePresenceSequence = snapshot.sequence;
327
+ /** THE PAINT CONDITION: a participant is on the stage its own presence
328
+ * names, so the same person's marker follows them from the Scene to a
329
+ * model document instead of being drawn on both. */
330
+ const here = snapshot.participants.filter(
331
+ (participant) =>
332
+ participant.participantId !== EDITOR_PARTICIPANT_ID &&
333
+ participant.presence.document === documentId,
334
+ );
335
+ const visible = here.filter((participant) => participant.presence.camera);
336
+ const liveIds = new Set(visible.map((participant) => participant.participantId));
337
+ for (const [participantId, marker] of remoteCameraMarkers) {
338
+ if (liveIds.has(participantId)) continue;
339
+ disposeRemoteCameraMarker(marker);
340
+ remoteCameraMarkers.delete(participantId);
341
+ }
342
+ for (const participant of visible) {
343
+ let marker = remoteCameraMarkers.get(participant.participantId);
344
+ if (!marker) {
345
+ marker = createRemoteCameraMarker(participant);
346
+ remoteCameraMarkers.set(participant.participantId, marker);
347
+ scene.add(marker.helper, marker.label);
348
+ }
349
+ updateRemoteCameraMarker(marker, participant);
350
+ }
351
+ const selected = here.flatMap((participant) =>
352
+ participant.presence.selection.slice(0, 20).map((objectId) => ({
353
+ key: `${participant.participantId}:${objectId}`,
354
+ objectId,
355
+ color: participant.color,
356
+ })),
357
+ );
358
+ const selectedKeys = new Set(selected.map((entry) => entry.key));
359
+ for (const [key, marker] of remoteSelectionMarkers) {
360
+ if (selectedKeys.has(key)) continue;
361
+ disposeRemoteSelectionMarker(marker);
362
+ remoteSelectionMarkers.delete(key);
363
+ }
364
+ for (const entry of selected) {
365
+ const object = store.objectMap.get(entry.objectId);
366
+ const previous = remoteSelectionMarkers.get(entry.key);
367
+ if (!object) {
368
+ if (previous) {
369
+ disposeRemoteSelectionMarker(previous);
370
+ remoteSelectionMarkers.delete(entry.key);
371
+ }
372
+ continue;
373
+ }
374
+ if (previous?.object === object) continue;
375
+ if (previous) disposeRemoteSelectionMarker(previous);
376
+ const marker = createRemoteSelectionMarker(object, entry.color);
377
+ remoteSelectionMarkers.set(entry.key, marker);
378
+ scene.add(marker.helper);
379
+ }
380
+ const rays = here.flatMap((participant) => {
381
+ const ray = pointerRayGesture(participant.presence.gesture);
382
+ return ray
383
+ ? [{ participantId: participant.participantId, color: participant.color, ray }]
384
+ : [];
385
+ });
386
+ const rayIds = new Set(rays.map((entry) => entry.participantId));
387
+ for (const [participantId, marker] of remoteRayMarkers) {
388
+ if (rayIds.has(participantId)) continue;
389
+ disposeRemoteRayMarker(marker);
390
+ remoteRayMarkers.delete(participantId);
391
+ }
392
+ for (const entry of rays) {
393
+ let marker = remoteRayMarkers.get(entry.participantId);
394
+ if (!marker) {
395
+ marker = createRemoteRayMarker(entry.color);
396
+ remoteRayMarkers.set(entry.participantId, marker);
397
+ scene.add(marker.line);
398
+ }
399
+ updateRemoteRayMarker(marker, entry.ray);
400
+ }
401
+ };
402
+
403
+ // "Join" in the header's people control lands the viewport on that
404
+ // participant's real reported camera.
405
+ const joinRequested = (event: Event): void => {
406
+ if (!publishes()) return;
407
+ const participantId = (event as CustomEvent<{ participantId?: unknown }>).detail?.participantId;
408
+ if (typeof participantId !== 'string') return;
409
+ const camera = collaborationSnapshot()?.participants.find(
410
+ (participant) => participant.participantId === participantId,
411
+ )?.presence.camera;
412
+ if (!camera) return;
413
+ store.setCameraPose(
414
+ { x: camera.x, y: camera.y, z: camera.z },
415
+ { x: camera.targetX, y: camera.targetY, z: camera.targetZ },
416
+ camera.fov,
417
+ );
418
+ };
419
+ window.addEventListener('editor:collaboration-join', joinRequested);
420
+
421
+ return {
422
+ reportCamera,
423
+ syncMarkers: (dtSeconds) => {
424
+ syncRemoteSpatialMarkers();
425
+ for (const marker of remoteCameraMarkers.values())
426
+ animateRemoteCameraMarker(marker, dtSeconds);
427
+ for (const marker of remoteSelectionMarkers.values()) {
428
+ contentWorldBounds(marker.object, marker.box);
429
+ }
430
+ },
431
+ dispose: () => {
432
+ viewport.orbitControls.removeEventListener('change', reportCamera);
433
+ viewport.transformControls.removeEventListener('dragging-changed', reportTransformGesture);
434
+ container.removeEventListener('pointermove', reportPointerRay);
435
+ container.removeEventListener('pointerleave', clearPointerRay);
436
+ window.removeEventListener('editor:collaboration-join', joinRequested);
437
+ for (const marker of remoteCameraMarkers.values()) disposeRemoteCameraMarker(marker);
438
+ remoteCameraMarkers.clear();
439
+ for (const marker of remoteSelectionMarkers.values()) disposeRemoteSelectionMarker(marker);
440
+ remoteSelectionMarkers.clear();
441
+ for (const marker of remoteRayMarkers.values()) disposeRemoteRayMarker(marker);
442
+ remoteRayMarkers.clear();
443
+ },
444
+ };
445
+ }
446
+
447
+ function createRemoteRayMarker(color: string): RemoteRayMarker {
448
+ const positions = new THREE.Float32BufferAttribute(new Float32Array(6), 3);
449
+ const geometry = new THREE.BufferGeometry();
450
+ geometry.setAttribute('position', positions);
451
+ const material = new THREE.LineBasicMaterial({
452
+ color: new THREE.Color(color),
453
+ depthTest: false,
454
+ transparent: true,
455
+ opacity: 0.9,
456
+ });
457
+ const line = new THREE.Line(geometry, material);
458
+ line.name = 'Collaboration pointer ray';
459
+ line.userData['editorOnly'] = true;
460
+ line.renderOrder = 10_001;
461
+ return { line, positions };
462
+ }
463
+
464
+ function updateRemoteRayMarker(
465
+ marker: RemoteRayMarker,
466
+ ray: { origin: THREE.Vector3; end: THREE.Vector3 },
467
+ ): void {
468
+ marker.positions.setXYZ(0, ray.origin.x, ray.origin.y, ray.origin.z);
469
+ marker.positions.setXYZ(1, ray.end.x, ray.end.y, ray.end.z);
470
+ marker.positions.needsUpdate = true;
471
+ marker.line.geometry.computeBoundingSphere();
472
+ }
473
+
474
+ function disposeRemoteRayMarker(marker: RemoteRayMarker): void {
475
+ marker.line.removeFromParent();
476
+ marker.line.geometry.dispose();
477
+ (marker.line.material as THREE.Material).dispose();
478
+ }