@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,345 @@
1
+ /// <reference lib="dom" />
2
+
3
+ import { readFile } from 'node:fs/promises';
4
+ import { createRequire } from 'node:module';
5
+ import { dirname, extname } from 'node:path';
6
+ import * as THREE from 'three';
7
+ import { GLTFExporter } from 'three/addons/exporters/GLTFExporter.js';
8
+ import { ColladaLoader } from 'three/addons/loaders/ColladaLoader.js';
9
+ import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
10
+ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
11
+ import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
12
+ import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
13
+ import { PLYLoader } from 'three/addons/loaders/PLYLoader.js';
14
+ import { STLLoader } from 'three/addons/loaders/STLLoader.js';
15
+ import { TDSLoader } from 'three/addons/loaders/TDSLoader.js';
16
+ import { mergeVertices } from 'three/addons/utils/BufferGeometryUtils.js';
17
+ import {
18
+ type AssetImportSettings,
19
+ assetImportSettingsSchema,
20
+ } from '../src/asset-workflow/import-contract';
21
+
22
+ export const SERVER_CONVERTIBLE_MODEL_FORMATS = new Set(['fbx', 'obj', 'dae', 'stl', 'ply', '3ds']);
23
+
24
+ /** Convert a staged source model to a runtime GLB without requiring Blender. */
25
+ export async function convertStagedModelToGlb(
26
+ primaryPath: string,
27
+ format: string,
28
+ rawSettings: Partial<AssetImportSettings> | number = {},
29
+ ): Promise<Uint8Array> {
30
+ const settings = assetImportSettingsSchema.parse(
31
+ typeof rawSettings === 'number' ? { scale: rawSettings } : rawSettings,
32
+ );
33
+ installNodeDom();
34
+ const bytes = new Uint8Array(await readFile(primaryPath));
35
+ const object = await parseSourceModel(primaryPath, format.toLowerCase(), bytes);
36
+ discardUnloadedTextures(object);
37
+ applyModelImportSettings(object, settings);
38
+ installNodeFileReader();
39
+ try {
40
+ const result = await new Promise<ArrayBuffer>((resolve, reject) => {
41
+ new GLTFExporter().parse(
42
+ object,
43
+ (output) =>
44
+ output instanceof ArrayBuffer
45
+ ? resolve(output)
46
+ : reject(new Error('Model conversion produced JSON instead of binary GLB.')),
47
+ reject,
48
+ { binary: true, animations: object.animations, onlyVisible: false },
49
+ );
50
+ });
51
+ const output = new Uint8Array(result);
52
+ await validateConvertedGlb(output);
53
+ return output;
54
+ } finally {
55
+ disposeObject(object);
56
+ }
57
+ }
58
+
59
+ const materialTextureSlots = [
60
+ 'map',
61
+ 'alphaMap',
62
+ 'aoMap',
63
+ 'bumpMap',
64
+ 'displacementMap',
65
+ 'emissiveMap',
66
+ 'envMap',
67
+ 'lightMap',
68
+ 'metalnessMap',
69
+ 'normalMap',
70
+ 'roughnessMap',
71
+ 'specularMap',
72
+ ] as const;
73
+
74
+ /** Apply the persisted conversion settings before the runtime GLB is exported. */
75
+ export function applyModelImportSettings(
76
+ object: THREE.Object3D,
77
+ settings: AssetImportSettings,
78
+ ): void {
79
+ object.scale.multiplyScalar(settings.scale * sourceUnitScale(settings.sourceUnits));
80
+ object.quaternion.premultiply(importAxisRotation(settings.upAxis, settings.forwardAxis));
81
+
82
+ const discardedTextures = new Set<THREE.Texture>();
83
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one traversal deliberately applies the persisted mesh, material, texture, normal, tangent, and optimization settings to each converted renderable.
84
+ object.traverse((node) => {
85
+ const mesh = node as THREE.Mesh;
86
+ if (!mesh.geometry) return;
87
+ let geometry = mesh.geometry;
88
+ if (settings.meshOptimization !== 'none') {
89
+ const optimized = mergeVertices(
90
+ geometry,
91
+ settings.meshOptimization === 'aggressive' ? 1e-3 : 1e-6,
92
+ );
93
+ if (optimized !== geometry) {
94
+ mesh.geometry = optimized;
95
+ geometry.dispose();
96
+ geometry = optimized;
97
+ }
98
+ }
99
+ if (settings.normals !== 'preserve') {
100
+ geometry.deleteAttribute('normal');
101
+ geometry.computeVertexNormals();
102
+ }
103
+ if (settings.tangents === 'discard') geometry.deleteAttribute('tangent');
104
+ if (
105
+ settings.tangents === 'generate' &&
106
+ geometry.index &&
107
+ geometry.hasAttribute('position') &&
108
+ geometry.hasAttribute('normal') &&
109
+ geometry.hasAttribute('uv')
110
+ ) {
111
+ geometry.computeTangents();
112
+ }
113
+ geometry.computeBoundingBox();
114
+ geometry.computeBoundingSphere();
115
+
116
+ const priorMaterials = Array.isArray(mesh.material)
117
+ ? mesh.material
118
+ : mesh.material
119
+ ? [mesh.material]
120
+ : [];
121
+ if (settings.materials === 'discard') {
122
+ mesh.material = Array.isArray(mesh.material)
123
+ ? priorMaterials.map(() => new THREE.MeshStandardMaterial())
124
+ : new THREE.MeshStandardMaterial();
125
+ for (const material of priorMaterials) material.dispose();
126
+ return;
127
+ }
128
+ if (settings.textures !== 'discard') return;
129
+ for (const material of priorMaterials) {
130
+ const textured = material as THREE.Material & Record<string, unknown>;
131
+ for (const slot of materialTextureSlots) {
132
+ const texture = textured[slot];
133
+ if (texture instanceof THREE.Texture) discardedTextures.add(texture);
134
+ textured[slot] = null;
135
+ }
136
+ material.needsUpdate = true;
137
+ }
138
+ });
139
+ for (const texture of discardedTextures) texture.dispose();
140
+
141
+ if (settings.animations.length > 0) {
142
+ const requested = new Set(settings.animations);
143
+ const selected = object.animations.filter((clip) => requested.has(clip.name));
144
+ const missing = settings.animations.filter(
145
+ (name) => !selected.some((clip) => clip.name === name),
146
+ );
147
+ if (missing.length > 0) throw new Error(`Animation clips not found: ${missing.join(', ')}.`);
148
+ object.animations = selected;
149
+ }
150
+ object.updateWorldMatrix(true, true);
151
+ }
152
+
153
+ function sourceUnitScale(units: AssetImportSettings['sourceUnits']): number {
154
+ return { auto: 1, mm: 0.001, cm: 0.01, m: 1, in: 0.0254, ft: 0.3048 }[units];
155
+ }
156
+
157
+ function importAxisRotation(
158
+ upAxis: AssetImportSettings['upAxis'],
159
+ forwardAxis: AssetImportSettings['forwardAxis'],
160
+ ): THREE.Quaternion {
161
+ const up = upAxis === 'auto' ? null : axisVector(upAxis);
162
+ const forward = forwardAxis === 'auto' ? null : axisVector(forwardAxis);
163
+ if (up && forward) {
164
+ if (Math.abs(up.dot(forward)) > 0.001)
165
+ throw new Error('Import up and forward axes must be perpendicular.');
166
+ const right = new THREE.Vector3().crossVectors(forward, up).normalize();
167
+ const correctedForward = new THREE.Vector3().crossVectors(up, right).normalize();
168
+ const sourceBasis = new THREE.Matrix4().makeBasis(right, up, correctedForward.clone().negate());
169
+ return new THREE.Quaternion().setFromRotationMatrix(sourceBasis.invert());
170
+ }
171
+ if (up) return new THREE.Quaternion().setFromUnitVectors(up, new THREE.Vector3(0, 1, 0));
172
+ if (forward)
173
+ return new THREE.Quaternion().setFromUnitVectors(forward, new THREE.Vector3(0, 0, -1));
174
+ return new THREE.Quaternion();
175
+ }
176
+
177
+ function axisVector(axis: Exclude<AssetImportSettings['forwardAxis'], 'auto'> | 'x' | 'y' | 'z') {
178
+ const sign = axis.startsWith('-') ? -1 : 1;
179
+ const name = axis.replace('-', '');
180
+ return new THREE.Vector3(
181
+ name === 'x' ? sign : 0,
182
+ name === 'y' ? sign : 0,
183
+ name === 'z' ? sign : 0,
184
+ );
185
+ }
186
+
187
+ async function parseSourceModel(
188
+ primaryPath: string,
189
+ format: string,
190
+ bytes: Uint8Array,
191
+ ): Promise<THREE.Object3D> {
192
+ const resourcePath = `${dirname(primaryPath)}/`;
193
+ switch (format) {
194
+ case 'fbx':
195
+ return new FBXLoader().parse(bytes.buffer as ArrayBuffer, resourcePath);
196
+ case 'obj': {
197
+ const loader = new OBJLoader();
198
+ const materialPath = primaryPath.replace(/\.obj$/i, '.mtl');
199
+ try {
200
+ const materials = new MTLLoader().parse(await readFile(materialPath, 'utf8'), resourcePath);
201
+ materials.preload();
202
+ loader.setMaterials(materials);
203
+ } catch {
204
+ // Geometry-only OBJ conversion remains valid when no MTL is present.
205
+ }
206
+ return loader.parse(new TextDecoder().decode(bytes));
207
+ }
208
+ case 'dae': {
209
+ return new ColladaLoader().parse(new TextDecoder().decode(bytes), resourcePath).scene;
210
+ }
211
+ case 'stl': {
212
+ const geometry = new STLLoader().parse(bytes.buffer as ArrayBuffer);
213
+ return new THREE.Mesh(
214
+ geometry,
215
+ new THREE.MeshStandardMaterial({ color: 0x8fb5da, roughness: 0.75 }),
216
+ );
217
+ }
218
+ case 'ply': {
219
+ const geometry = new PLYLoader().parse(bytes.buffer as ArrayBuffer);
220
+ if (!geometry.hasAttribute('normal')) geometry.computeVertexNormals();
221
+ return new THREE.Mesh(
222
+ geometry,
223
+ new THREE.MeshStandardMaterial({
224
+ color: geometry.hasAttribute('color') ? 0xffffff : 0xb8d09b,
225
+ vertexColors: geometry.hasAttribute('color'),
226
+ roughness: 0.8,
227
+ side: THREE.DoubleSide,
228
+ }),
229
+ );
230
+ }
231
+ case '3ds':
232
+ return new TDSLoader().parse(bytes.buffer as ArrayBuffer, resourcePath);
233
+ default:
234
+ throw new Error(`Built-in conversion does not support ${format || extname(primaryPath)}.`);
235
+ }
236
+ }
237
+
238
+ /** Three's source loaders construct browser image elements even when the
239
+ * conversion runs in Node. JSDOM supplies that parser boundary; unresolved
240
+ * asynchronous images are removed below rather than passed to GLTFExporter
241
+ * as invalid zero-sized image objects. */
242
+ function installNodeDom(): void {
243
+ if (typeof document !== 'undefined' && typeof DOMParser !== 'undefined') return;
244
+ const { JSDOM } = createRequire(import.meta.url)('jsdom') as {
245
+ JSDOM: new () => {
246
+ window: {
247
+ document: Document;
248
+ DOMParser: typeof DOMParser;
249
+ HTMLImageElement: typeof HTMLImageElement;
250
+ HTMLCanvasElement: typeof HTMLCanvasElement;
251
+ Image: typeof Image;
252
+ };
253
+ };
254
+ };
255
+ const window = new JSDOM().window;
256
+ Object.assign(globalThis, {
257
+ document: window.document,
258
+ DOMParser: window.DOMParser,
259
+ HTMLImageElement: window.HTMLImageElement,
260
+ HTMLCanvasElement: window.HTMLCanvasElement,
261
+ Image: window.Image,
262
+ });
263
+ }
264
+
265
+ function discardUnloadedTextures(root: THREE.Object3D): void {
266
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one bounded traversal removes only unresolved image slots across every supported material shape.
267
+ root.traverse((object) => {
268
+ const mesh = object as THREE.Mesh;
269
+ const materials = Array.isArray(mesh.material)
270
+ ? mesh.material
271
+ : mesh.material
272
+ ? [mesh.material]
273
+ : [];
274
+ for (const material of materials) {
275
+ const textured = material as THREE.Material & Record<string, unknown>;
276
+ for (const slot of materialTextureSlots) {
277
+ const value = textured[slot];
278
+ if (!(value instanceof THREE.Texture)) continue;
279
+ const image = value.image as { width?: number; height?: number } | null;
280
+ if (image && (image.width ?? 0) > 0 && (image.height ?? 0) > 0) continue;
281
+ textured[slot] = null;
282
+ value.dispose();
283
+ }
284
+ material.needsUpdate = true;
285
+ }
286
+ });
287
+ }
288
+
289
+ async function validateConvertedGlb(bytes: Uint8Array): Promise<void> {
290
+ const parsed = await new GLTFLoader().parseAsync(Uint8Array.from(bytes).buffer, '');
291
+ let renderable = false;
292
+ parsed.scene.traverse((object) => {
293
+ renderable ||= Boolean((object as THREE.Mesh).isMesh || (object as THREE.Points).isPoints);
294
+ });
295
+ disposeObject(parsed.scene);
296
+ if (!renderable && parsed.animations.length === 0) {
297
+ throw new Error('Converted GLB contains neither renderable geometry nor animation clips.');
298
+ }
299
+ }
300
+
301
+ function installNodeFileReader(): void {
302
+ if (typeof FileReader !== 'undefined') return;
303
+ class NodeFileReader {
304
+ result: string | ArrayBuffer | null = null;
305
+ error: Error | null = null;
306
+ onloadend: ((event: ProgressEvent<FileReader>) => void) | null = null;
307
+ onerror: ((event: ProgressEvent<FileReader>) => void) | null = null;
308
+ readAsArrayBuffer(blob: Blob): void {
309
+ void blob.arrayBuffer().then(
310
+ (result) => {
311
+ this.result = result;
312
+ this.onloadend?.({ target: this } as unknown as ProgressEvent<FileReader>);
313
+ },
314
+ (error) => {
315
+ this.error = error instanceof Error ? error : new Error(String(error));
316
+ this.onerror?.({ target: this } as unknown as ProgressEvent<FileReader>);
317
+ },
318
+ );
319
+ }
320
+ readAsDataURL(blob: Blob): void {
321
+ void blob.arrayBuffer().then((result) => {
322
+ this.result = `data:${blob.type || 'application/octet-stream'};base64,${Buffer.from(result).toString('base64')}`;
323
+ this.onloadend?.({ target: this } as unknown as ProgressEvent<FileReader>);
324
+ });
325
+ }
326
+ }
327
+ Object.assign(globalThis, { FileReader: NodeFileReader });
328
+ }
329
+
330
+ function disposeObject(root: THREE.Object3D): void {
331
+ root.traverse((object) => {
332
+ const renderable = object as THREE.Mesh;
333
+ renderable.geometry?.dispose();
334
+ const materials = Array.isArray(renderable.material)
335
+ ? renderable.material
336
+ : renderable.material
337
+ ? [renderable.material]
338
+ : [];
339
+ for (const material of materials) {
340
+ for (const value of Object.values(material))
341
+ if (value instanceof THREE.Texture) value.dispose();
342
+ material.dispose();
343
+ }
344
+ });
345
+ }
@@ -0,0 +1,162 @@
1
+ export type CredentialPersistence = 'system' | 'session';
2
+
3
+ export interface NativeCredentialStore {
4
+ persistence(): Promise<CredentialPersistence>;
5
+ read(account: string): Promise<string | null>;
6
+ write(account: string, value: string): Promise<void>;
7
+ delete(account: string): Promise<void>;
8
+ }
9
+
10
+ /**
11
+ * Normalized per-credential handle over `@napi-rs/keyring`'s `AsyncEntry` /
12
+ * `Entry` classes. Restores keytar's calmer contract: a missing credential is
13
+ * `null` / `false`, never an error.
14
+ */
15
+ interface KeyringEntry {
16
+ getPassword(): Promise<string | null>;
17
+ setPassword(value: string): Promise<void>;
18
+ deletePassword(): Promise<boolean>;
19
+ }
20
+
21
+ type KeyringEntryFactory = (service: string, account: string) => KeyringEntry;
22
+
23
+ type KeyringLoader = () => Promise<unknown>;
24
+
25
+ interface RawKeyringEntry {
26
+ getPassword(): unknown;
27
+ setPassword(value: string): unknown;
28
+ deleteCredential?(): unknown;
29
+ deletePassword?(): unknown;
30
+ }
31
+
32
+ type RawEntryConstructor = new (service: string, account: string) => RawKeyringEntry;
33
+
34
+ /**
35
+ * `keyring-rs` reports an absent credential as a NoEntry error. Message text
36
+ * varies by binding/version: keyring-rs v2/v3 says "No matching entry found
37
+ * in secure storage", while the actually-shipped `@napi-rs/keyring@^1.3.0`
38
+ * native binary says "No matching credential found" (confirmed via `strings`
39
+ * on the installed binary). keytar returned `null`/`false` for the same
40
+ * situation; treat NoEntry as "not found", not as a broken credential manager,
41
+ * regardless of which wording the binding uses.
42
+ */
43
+ function isNoEntryError(error: unknown): boolean {
44
+ return error instanceof Error && /no matching (entry|credential)/i.test(error.message);
45
+ }
46
+
47
+ function keyringApi(module: unknown): KeyringEntryFactory | null {
48
+ if (!module || typeof module !== 'object') return null;
49
+ const imported = module as Record<string, unknown>;
50
+ const candidate =
51
+ imported['default'] && typeof imported['default'] === 'object'
52
+ ? (imported['default'] as Record<string, unknown>)
53
+ : imported;
54
+ // Prefer AsyncEntry (does not block the event loop); accept sync Entry too.
55
+ const EntryConstructor = [candidate['AsyncEntry'], candidate['Entry']].find(
56
+ (value): value is RawEntryConstructor =>
57
+ typeof value === 'function' &&
58
+ typeof (value as { prototype?: Record<string, unknown> }).prototype?.['getPassword'] ===
59
+ 'function' &&
60
+ typeof (value as { prototype?: Record<string, unknown> }).prototype?.['setPassword'] ===
61
+ 'function',
62
+ );
63
+ if (!EntryConstructor) return null;
64
+ return (service, account) => {
65
+ const entry = new EntryConstructor(service, account);
66
+ return {
67
+ async getPassword() {
68
+ try {
69
+ const value = await entry.getPassword();
70
+ return typeof value === 'string' ? value : null;
71
+ } catch (error) {
72
+ if (isNoEntryError(error)) return null;
73
+ throw error;
74
+ }
75
+ },
76
+ async setPassword(value) {
77
+ await entry.setPassword(value);
78
+ },
79
+ async deletePassword() {
80
+ try {
81
+ const deleted =
82
+ typeof entry.deleteCredential === 'function'
83
+ ? await entry.deleteCredential()
84
+ : await entry.deletePassword?.();
85
+ return deleted !== false;
86
+ } catch (error) {
87
+ if (isNoEntryError(error)) return false;
88
+ throw error;
89
+ }
90
+ },
91
+ };
92
+ };
93
+ }
94
+
95
+ /**
96
+ * One editor-global secret boundary. Native builds use macOS Keychain,
97
+ * Windows Credential Manager, or Linux Secret Service through
98
+ * `@napi-rs/keyring`, the maintained native credential-store binding. A host
99
+ * without that optional dependency is deliberately session-only: it never
100
+ * turns a missing credential manager into a plaintext file.
101
+ */
102
+ export function createNativeCredentialStore(
103
+ service = 'ai.vgai.editor',
104
+ loadKeyring: KeyringLoader = () => import('@napi-rs/keyring'),
105
+ ): NativeCredentialStore {
106
+ const memory = new Map<string, string>();
107
+ let modulePromise: Promise<KeyringEntryFactory | null> | undefined;
108
+ let degraded = false;
109
+ const keyring = () => {
110
+ modulePromise ??= loadKeyring()
111
+ .then(keyringApi)
112
+ .catch(() => null);
113
+ return modulePromise;
114
+ };
115
+
116
+ return {
117
+ async persistence() {
118
+ return (await keyring()) && !degraded ? 'system' : 'session';
119
+ },
120
+ async read(account) {
121
+ const native = await keyring();
122
+ if (native && !degraded) {
123
+ try {
124
+ const value = await native(service, account).getPassword();
125
+ if (value === null) memory.delete(account);
126
+ else memory.set(account, value);
127
+ return value;
128
+ } catch {
129
+ degraded = true;
130
+ }
131
+ }
132
+ return memory.get(account) ?? null;
133
+ },
134
+ async write(account, value) {
135
+ const native = await keyring();
136
+ if (native && !degraded) {
137
+ try {
138
+ await native(service, account).setPassword(value);
139
+ memory.set(account, value);
140
+ return;
141
+ } catch {
142
+ degraded = true;
143
+ }
144
+ }
145
+ memory.set(account, value);
146
+ },
147
+ async delete(account) {
148
+ const native = await keyring();
149
+ if (native) {
150
+ try {
151
+ await native(service, account).deletePassword();
152
+ } catch {
153
+ degraded = true;
154
+ throw new Error(
155
+ 'The native credential manager could not confirm that the credential was deleted.',
156
+ );
157
+ }
158
+ }
159
+ memory.delete(account);
160
+ },
161
+ };
162
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * THE platform browser hand-off — the one open ladder (darwin / win32 / WSL
3
+ * explorer.exe→powershell.exe / xdg-open), owned here because the editor
4
+ * server must keep maintaining its tab (tab-bijection self-heal,
5
+ * ensure-driven opens) long after any launching CLI process has exited. The
6
+ * CLI imports this module; it does not carry its own copy — the old
7
+ * "no editor-package dependency" premise stopped being true when the CLI
8
+ * grew six editor-server imports and an `@vgai/editor` dependency, and the
9
+ * two ladders had already drifted (`-g` background support on one side
10
+ * only).
11
+ */
12
+
13
+ import { existsSync, readFileSync } from 'node:fs';
14
+ import { spawnOpener } from './spawn-opener';
15
+
16
+ function isWSL(): boolean {
17
+ if (process.platform !== 'linux') return false;
18
+ try {
19
+ return readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * The path segment that identifies a session rooted in an AGENT's git
27
+ * worktree. Agents take one of these before they write code
28
+ * (docs/LOCAL-DEV.md), so it is the one honest, always-present signal that a
29
+ * tab belongs to a background builder rather than to the person at the
30
+ * keyboard.
31
+ */
32
+ const AGENT_WORKTREE_MARKER = '/.claude/worktrees/';
33
+
34
+ /** Env override for the placement decision (`1` background, `0` foreground). */
35
+ export const TAB_BACKGROUND_ENV = 'VGAI_TAB_BACKGROUND';
36
+
37
+ export interface TabOpenPlacementInput {
38
+ /**
39
+ * The session's project root, ALREADY symlink-resolved
40
+ * (`canonicalProjectRoot`) — the marker check is on the real path, because
41
+ * a worktree reached through a symlinked parent would otherwise read as a
42
+ * human checkout.
43
+ */
44
+ readonly projectRoot: string | null | undefined;
45
+ readonly env: Readonly<Record<string, string | undefined>>;
46
+ }
47
+
48
+ /**
49
+ * Decide whether this session's ONE tab should open behind the human's
50
+ * current window instead of stealing focus.
51
+ *
52
+ * Measured (owner, three times in one day): every builder/reviewer `vgai edit`
53
+ * auto-opened a FOREGROUND tab on the one display, so the owner kept ending up
54
+ * looking at an agent's session instead of their own. A session rooted in an
55
+ * agent worktree therefore opens in the BACKGROUND; the human flow — a normal
56
+ * checkout, or a scaffolded game anywhere else — keeps foreground, because for
57
+ * a person the whole point of `vgai edit` is that the editor comes up in front
58
+ * of them.
59
+ *
60
+ * `VGAI_TAB_BACKGROUND` overrides in BOTH directions: `1` backgrounds a tab
61
+ * that would have been foreground, `0` foregrounds one inside a worktree (an
62
+ * agent deliberately showing the owner something).
63
+ *
64
+ * Pure: the caller supplies the resolved root and the environment.
65
+ */
66
+ export function shouldOpenTabInBackground(input: TabOpenPlacementInput): boolean {
67
+ const override = input.env[TAB_BACKGROUND_ENV];
68
+ if (override !== undefined && override !== '') {
69
+ return override !== '0' && override.toLowerCase() !== 'false';
70
+ }
71
+ const root = input.projectRoot;
72
+ if (root === null || root === undefined || root === '') return false;
73
+ return root.replaceAll('\\', '/').includes(AGENT_WORKTREE_MARKER);
74
+ }
75
+
76
+ export interface OpenBrowserUrlOptions {
77
+ /**
78
+ * Open behind the frontmost window instead of activating the browser.
79
+ * Honored on macOS only (`open -g`) — Windows `start` and `xdg-open` have no
80
+ * portable equivalent, so every other platform keeps its existing
81
+ * focus-stealing behavior rather than getting a half-kept promise.
82
+ */
83
+ readonly background?: boolean;
84
+ }
85
+
86
+ /** Best-effort open of `browserUrl` in the platform default browser. */
87
+ export function openBrowserUrl(browserUrl: string, options?: OpenBrowserUrlOptions): void {
88
+ if (process.platform === 'darwin') {
89
+ // `-g` = do not bring the opened application to the foreground. The tab
90
+ // still opens, still loads, and still registers with the bijection — it
91
+ // just does not seize the display.
92
+ spawnOpener('open', options?.background === true ? ['-g', browserUrl] : [browserUrl]);
93
+ } else if (process.platform === 'win32') {
94
+ // `start` is a cmd builtin, not an executable — it needs cmd itself.
95
+ spawnOpener('cmd', ['/c', 'start', '', browserUrl]);
96
+ } else if (isWSL()) {
97
+ // WSL has no display of its own; hand the URL to the Windows side. A dead
98
+ // interop socket (stale background session) means no Windows .exe can
99
+ // launch — name it instead of failing silently.
100
+ const interop = process.env['WSL_INTEROP'];
101
+ if (interop && !existsSync(interop)) {
102
+ console.error(
103
+ `[vgai-editor] cannot open a browser from this shell — the WSL interop socket ` +
104
+ `(${interop}) is gone, so Windows executables cannot launch. Open ${browserUrl} ` +
105
+ 'from any regular terminal or browser instead.',
106
+ );
107
+ return;
108
+ }
109
+ // Explorer is the direct Windows shell-association path. Start-Process
110
+ // can exit zero even when a transient browser process fails to forward
111
+ // the URL to the existing browser, so PowerShell is the fallback.
112
+ spawnOpener('explorer.exe', [browserUrl], () =>
113
+ spawnOpener('powershell.exe', ['-NoProfile', '-Command', `Start-Process '${browserUrl}'`]),
114
+ );
115
+ } else {
116
+ spawnOpener('xdg-open', [browserUrl]);
117
+ }
118
+ }