@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,162 @@
1
+ /**
2
+ * Reading and writing the project's own files.
3
+ *
4
+ * `public/` operations route through the backend-agnostic `StorageBackend`
5
+ * (`../storage`): `HttpStorage` over the same `/__editor/*` routes, wrapped by
6
+ * the frame's file door once its provider lands.
7
+ *
8
+ * The SPA-fallback check here is load-bearing: a dev server answers 200 with
9
+ * the editor's own `index.html` for a missing file, so "did I get the file"
10
+ * cannot be asked of the status code alone.
11
+ */
12
+
13
+ import { resolveUrl } from '@volter/editor-threejs/loader';
14
+ import { base64ToBytes } from '../bytes-codec';
15
+ import { getStorageBackend } from '../storage';
16
+ /**
17
+ * Read a project text file from the session that owns the project namespace.
18
+ *
19
+ * The storage backend is NOT the door here: `HttpStorage` is rooted at
20
+ * `public/`, not at the project root, so asking it for `src/...` produces a
21
+ * known-false asset-list 404 before the real Vite read. This goes directly to
22
+ * HTTP. Returns null when the file is not served.
23
+ */
24
+ export async function readProjectTextFile(path: string): Promise<string | null> {
25
+ try {
26
+ const res = await fetch(resolveUrl(path));
27
+ if (res.ok) return await res.text();
28
+ } catch {
29
+ /* ignore */
30
+ }
31
+ return null;
32
+ }
33
+
34
+ /**
35
+ * What a probe can honestly conclude about a project file. THREE answers,
36
+ * because "no" and "I could not tell" are different facts and a boolean has
37
+ * to spend one of them.
38
+ */
39
+ export type ProjectFilePresence = 'present' | 'absent' | 'unreachable';
40
+
41
+ /**
42
+ * A 200 that is really the SPA FALLBACK, not the file.
43
+ *
44
+ * MEASURED, dev server, project root `public/ingest/cuberun/` (which owns no
45
+ * `vgai.adapter.ts`):
46
+ *
47
+ * curl -sI /vgai.adapter.ts -> 200, Content-Type: text/html (index.html)
48
+ * curl -sI /vgai.project.json -> 200, Content-Type: application/json; charset=utf-8
49
+ *
50
+ * The fallback serves the editor's own `index.html`, so it is identifiable by
51
+ * the one thing it cannot hide: it is an HTML DOCUMENT. Nothing this probe is
52
+ * ever pointed at — a module, a manifest, an asset — is served as `text/html`,
53
+ * and the storage backend answers first for anything that could be.
54
+ *
55
+ * This shape is not dev-only: `docs/DEPLOY.md` §Surface 3 specifies serving
56
+ * `dist/` with an index.html fallback, i.e. "a missing asset returns
57
+ * `index.html`". Both shipped surfaces answer the same way.
58
+ */
59
+ function isSpaFallbackDocument(response: Response): boolean {
60
+ return (response.headers.get('content-type') ?? '').toLowerCase().includes('text/html');
61
+ }
62
+
63
+ /**
64
+ * Does this project file exist? — CONTENT-DISCRIMINATED, because on both
65
+ * surfaces this product ships an existence probe that trusts `res.ok` is a
66
+ * constant `true`.
67
+ *
68
+ * `HttpStorage` is deliberately rooted at
69
+ * `public/`, while this probe accepts project-root paths such as
70
+ * `src/prefabs/Player.tsx`; asking that backend first turns an ordinary source
71
+ * probe into a noisy `/__editor/assets?dir=src` 404. This therefore
72
+ * asks Vite directly with HEAD. Both routes remain existence-only — neither
73
+ * downloads the file body.
74
+ *
75
+ * The HTTP probe classifies rather than trusting `res.ok`:
76
+ *
77
+ * - not ok -> `absent` (a real 404 from a real route);
78
+ * - ok + `text/html` -> `absent` — {@link isSpaFallbackDocument}, the
79
+ * measured false positive;
80
+ * - ok, anything else -> `present` (a real file answering with its own
81
+ * content type);
82
+ * - the fetch throws -> `unreachable`. NOT `absent`: an unanswered probe is
83
+ * a fact about the transport, and a caller that must not act on a guess
84
+ * (see `project-adapter.ts`, which chooses a BINDING TABLE off this) is
85
+ * entitled to know the difference.
86
+ *
87
+ * This function's earlier docblock already recorded the false positive —
88
+ * "the dev server's SPA fallback also answers a HEAD/GET for a MISSING path
89
+ * with 200 (it serves `index.html` rather than 404), so `res.ok` alone cannot
90
+ * fully distinguish 'exists' from 'missing'" — and dismissed it as harmless
91
+ * because "a false positive here just means a subsequent real open attempt
92
+ * fails through its own error path". That held for the then-only caller
93
+ * (`workspace-state-persistence`, probing `public/`-rooted asset paths the
94
+ * storage backend answers authoritatively). It stopped holding the moment a
95
+ * project-ROOT path was probed AHEAD of a branch that would otherwise have
96
+ * succeeded: the "own error path" then reports a load failure for a file the
97
+ * project never had, and the real binding is never reached. The discrimination
98
+ * lives HERE, inside the probe, so the next caller cannot re-inherit the blind
99
+ * question.
100
+ */
101
+ export async function probeProjectFile(path: string): Promise<ProjectFilePresence> {
102
+ // Ask the origin; the fallback detector below keeps a SPA 200 from counting
103
+ // as the file.
104
+ try {
105
+ const res = await fetch(resolveUrl(path), { method: 'HEAD' });
106
+ if (!res.ok) return 'absent';
107
+ return isSpaFallbackDocument(res) ? 'absent' : 'present';
108
+ } catch {
109
+ return 'unreachable';
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Check whether a project file exists WITHOUT reading its content — the
115
+ * boolean face of {@link probeProjectFile}, for callers with nothing to do
116
+ * about the difference between "no" and "could not tell". Prefer this over
117
+ * `readProjectTextFile(...) !== null` when only existence is needed, since
118
+ * that reads and discards the whole body.
119
+ */
120
+ export async function projectFileExists(path: string): Promise<boolean> {
121
+ return (await probeProjectFile(path)) === 'present';
122
+ }
123
+
124
+ /** Save a file to public/. Returns true on success. */
125
+ export async function saveFile(
126
+ path: string,
127
+ content: string,
128
+ encoding?: 'base64',
129
+ ): Promise<boolean> {
130
+ try {
131
+ // base64 content → raw bytes; the backend re-encodes per its transport.
132
+ // `base64ToBytes` is a LOOP; `Uint8Array.from(atob(…), (c) => …)` calls the
133
+ // mapping callback once per CHARACTER (measured 27.7x slower at 3MB).
134
+ const data: string | Uint8Array = encoding === 'base64' ? base64ToBytes(content) : content;
135
+ await getStorageBackend().write(path, data);
136
+ return true;
137
+ } catch {
138
+ return false;
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Project-relative source files matching `globs` (`src/models/**\/*.ts`; `*`
144
+ * within a segment, `**` across segments) — what a finder's `include`
145
+ * reads through (`FinderInput.sources`), answered by the session's
146
+ * `/__editor/source-files` route.
147
+ */
148
+ export async function listProjectSourceFiles(
149
+ globs: readonly string[],
150
+ options: { readonly order?: 'name' | 'mtime' } = {},
151
+ ): Promise<string[]> {
152
+ if (globs.length === 0) return [];
153
+ const res = await fetch(
154
+ `/__editor/source-files?${new URLSearchParams([
155
+ ...globs.map((g): [string, string] => ['include', g]),
156
+ ...(options.order === 'mtime' ? [['order', 'mtime'] as [string, string]] : []),
157
+ ])}`,
158
+ );
159
+ if (!res.ok) return [];
160
+ const body = (await res.json()) as { files?: string[] };
161
+ return body.files ?? [];
162
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * What the session currently IS, as the editor's own UI reads it: the server
3
+ * validation log, the editor lease identity, and the durable
4
+ * `.vgai/editor-state.json` view/tool state.
5
+ *
6
+ */
7
+
8
+ import type { LeasePollResult } from '../editor-lease';
9
+ import { assertEditorServerResponse, editorServerJson } from '../editor-server-response';
10
+ import { BASE } from './base';
11
+ /**
12
+ * PD-13: the validation failures and authoring warnings the dev server knows
13
+ * about RIGHT NOW, pre-formatted as `server-log` payloads. `editor-console.ts`
14
+ * pulls this once per connection to render what the live broadcast could not
15
+ * deliver — see `connectServerLogs` for why a pull rather than a push. THROWS
16
+ * on any failure, including a server that predates the endpoint and an origin
17
+ * whose page fallback answered instead; the one caller treats a failed replay
18
+ * as "nothing to replay" and says why.
19
+ */
20
+ export async function getServerValidationLog(): Promise<{ level: string; message: string }[]> {
21
+ const res = await fetch(`${BASE}/validation-log`);
22
+ const data = await editorServerJson<{ entries?: { level: string; message: string }[] }>(
23
+ res,
24
+ 'Could not read the server validation log',
25
+ );
26
+ return data.entries ?? [];
27
+ }
28
+
29
+ /**
30
+ * One liveness poll for the editor-lease watchdog (editor-lease.ts): ask the
31
+ * server on THIS tab's origin who it is. Reuses the same `/__editor/project`
32
+ * identity endpoint the CLI probes (`session.pid` + the served project path) —
33
+ * a replaced server on the same port answers with a new pid, which is how the
34
+ * watchdog detects a takeover.
35
+ *
36
+ * `ok: false` is any reason the reading is unusable — connection refused (the
37
+ * server is gone), a non-OK status, a timeout, or a malformed body — folded
38
+ * into one "failed poll" the reducer counts toward `server-gone`. The timeout
39
+ * is short: this runs every few seconds and a hung request should read as a
40
+ * failure, not stall the poll.
41
+ */
42
+ export async function pollEditorLeaseIdentity(timeoutMs = 3000): Promise<LeasePollResult> {
43
+ // Browser mode has no Node server to lease from; the watchdog never mounts
44
+ // there, but guard anyway so a stray call can never false-void a page.
45
+ if (typeof fetch === 'undefined') return { ok: false };
46
+ try {
47
+ const res = await fetch(`${BASE}/project`, { signal: AbortSignal.timeout(timeoutMs) });
48
+ const body = await editorServerJson<{
49
+ project?: { path?: unknown } | null;
50
+ session?: { pid?: unknown } | null;
51
+ }>(res, 'Editor lease poll failed');
52
+ return {
53
+ ok: true,
54
+ identity: {
55
+ project: typeof body.project?.path === 'string' ? body.project.path : null,
56
+ pid: typeof body.session?.pid === 'number' ? body.session.pid : null,
57
+ },
58
+ };
59
+ } catch {
60
+ return { ok: false };
61
+ }
62
+ }
63
+
64
+ // ---------------------------------------------------------------------------
65
+ // Persistent editor state (.vgai/editor-state.json)
66
+ // ---------------------------------------------------------------------------
67
+
68
+ /** Load persisted editor state (remembered transform mode/snap/last
69
+ * scene/camera). Returns {} if none exists. */
70
+ export async function loadEditorState(): Promise<Record<string, unknown>> {
71
+ try {
72
+ const res = await fetch(`${BASE}/editor-state`);
73
+ return await editorServerJson<Record<string, unknown>>(res, 'Could not read editor state');
74
+ } catch {
75
+ return {};
76
+ }
77
+ }
78
+
79
+ /** Set once the write below has reported a failure, so an autosave that fires
80
+ * on every viewport change reports a permanently broken origin ONCE. */
81
+ let reportedEditorStateWriteFailure = false;
82
+
83
+ /** Save editor state (persisted in .vgai/editor-state.json — see
84
+ * `loadEditorState`'s doc comment for the browser-mode routing).
85
+ *
86
+ * The boolean is this function's only channel and its one caller
87
+ * (`editor-shell-store.savePersistentState`) discards it, so the failure is
88
+ * ALSO logged: `res.ok` used to read a page fallback as a completed write,
89
+ * and a silent false would be the same lie one indirection later. */
90
+ export async function saveEditorState(state: Record<string, unknown>): Promise<boolean> {
91
+ try {
92
+ const res = await fetch(`${BASE}/editor-state`, {
93
+ method: 'POST',
94
+ headers: { 'Content-Type': 'application/json' },
95
+ body: JSON.stringify(state),
96
+ });
97
+ assertEditorServerResponse(res, 'Could not save editor state');
98
+ return true;
99
+ } catch (cause) {
100
+ if (!reportedEditorStateWriteFailure) {
101
+ reportedEditorStateWriteFailure = true;
102
+ // biome-ignore lint/suspicious/noConsole: the editor console captures console.error session-wide — this IS the report channel for a caller that discards the boolean.
103
+ console.error(cause instanceof Error ? cause.message : String(cause));
104
+ }
105
+ return false;
106
+ }
107
+ }
@@ -0,0 +1,268 @@
1
+ /**
2
+ * What a TAB reports upstream: its state snapshot, that it picked a command
3
+ * up, that a command finished, which play-boot phase it is in — plus the
4
+ * gameplay recording sink.
5
+ *
6
+ * The editor-state reporter serializes and coalesces on purpose. One user
7
+ * action can change several things at once (a Play click changes both play
8
+ * state and the active viewport), so only the newest waiting snapshot is kept
9
+ * and sends are serialized — an older, slower report can never land after a
10
+ * newer one and roll `/__editor/state` back.
11
+ */
12
+
13
+ import {
14
+ EDITOR_CLIENT_ID,
15
+ reportTabPhase,
16
+ sendCommandResultControl,
17
+ sendControl,
18
+ } from '../editor-presence';
19
+ import { assertEditorServerAnswered } from '../editor-server-response';
20
+ import { BASE } from './base';
21
+
22
+ // State reports can be triggered by several browser-owned transitions at once
23
+ // (a Play click changes both play state and the active viewport, for example).
24
+ // Keep only the newest waiting snapshot and serialize sends so an older,
25
+ // slower report can never land after a newer one and roll `/__editor/state`
26
+ // back.
27
+ let pendingEditorState: Record<string, unknown> | null = null;
28
+ let editorStateReportDrain: Promise<void> | null = null;
29
+
30
+ async function drainEditorStateReports(): Promise<void> {
31
+ while (pendingEditorState) {
32
+ const state = pendingEditorState;
33
+ pendingEditorState = null;
34
+ await sendControl('state', { ...state, _clientId: EDITOR_CLIENT_ID });
35
+ }
36
+ editorStateReportDrain = null;
37
+ // A caller cannot interleave with the synchronous block above, but keep
38
+ // this defensive restart so future refactors cannot strand a late report.
39
+ if (pendingEditorState) editorStateReportDrain = drainEditorStateReports();
40
+ }
41
+
42
+ /** Report the current editor state to the server (called by command-listener). */
43
+ export function reportEditorState(state: Record<string, unknown>): Promise<void> {
44
+ pendingEditorState = state;
45
+ editorStateReportDrain ??= drainEditorStateReports();
46
+ return editorStateReportDrain;
47
+ }
48
+
49
+ /**
50
+ * Tell the server this tab PICKED UP a relayed command — sent before the work
51
+ * starts, so it says "my command listener is running", nothing about the
52
+ * outcome.
53
+ *
54
+ * Long-budget commands (`play` waits out a whole async `setup()`) used to give
55
+ * a tab that had stopped answering the control channel the same silence as a tab
56
+ * that was merely busy, and the caller waited the entire budget for a result
57
+ * that was never coming. This receipt is what separates the two — see
58
+ * `server/server-utils.ts`'s `RELAY_DELIVERY_ACK_MS`. Best-effort and
59
+ * deliberately not awaited by the caller: a lost receipt costs a fast, named
60
+ * refusal, never a wrong result.
61
+ */
62
+ export async function reportCommandReceived(requestId: string): Promise<void> {
63
+ await sendControl('command-received', { _requestId: requestId, _clientId: EDITOR_CLIENT_ID });
64
+ }
65
+
66
+ /**
67
+ * Tell the server whether this page is RUNNING a command listener at all.
68
+ *
69
+ * The receipt above answers that question one command at a time, and only
70
+ * after somebody sends a command. This answers it standing, at the two moments
71
+ * that change the answer — `connectCommandListener` attaching, and its
72
+ * teardown running — so `vgai status` can name a dead page on the FIRST read
73
+ * instead of it being inferable only from a command that hangs.
74
+ *
75
+ * It is worth its own message because presence cannot carry it: the control
76
+ * channel is opened by the tiny pre-React entry
77
+ * (`early-editor-presence.ts`), long before the React graph that owns the
78
+ * listener finishes loading — so a page that dies in between connects,
79
+ * beats, and executes nothing.
80
+ */
81
+ export async function reportCommandListener(attached: boolean): Promise<void> {
82
+ await sendControl('command-listener', { _clientId: EDITOR_CLIENT_ID, attached });
83
+ }
84
+
85
+ /**
86
+ * Tell the server which play-boot step this page is ENTERING.
87
+ *
88
+ * Sent before the step's work, never after it, so a step that never returns is
89
+ * still named — see `play-boot-phase.ts` for the 199.5-second block that made
90
+ * three consecutive commands time out against a session every reader called
91
+ * healthy. Not awaited by the caller: the phase is diagnostics, and diagnostics
92
+ * that can delay a boot are worse than none.
93
+ */
94
+ export function reportPlayBootPhase(state: {
95
+ phase: string | null;
96
+ at: number;
97
+ run: number;
98
+ }): void {
99
+ // Two roads, because the control socket is the PAGE's: a phase announced
100
+ // right before a synchronous block sat in the page's send queue until the
101
+ // block ended (measured 2026-09-06: a 45 s build's phase arrived after the
102
+ // build). The heartbeat worker's socket keeps beating through the block,
103
+ // so the phase rides the next beat too; whichever lands first wins.
104
+ reportTabPhase(state.phase);
105
+ void sendControl('play-phase', { _clientId: EDITOR_CLIENT_ID, ...state });
106
+ }
107
+
108
+ /** Report a command result back to the server so the SDK/CLI gets the response.
109
+ * `data` carries an optional payload for commands that answer with data
110
+ * (e.g. `capture-viewport`'s base64 PNG, the debug-seam reads)
111
+ * forwarded verbatim through `/__editor/command-result` →
112
+ * `commandResponseFor` → the SDK transports, on the failure path too (where
113
+ * it carries structured `{ code: ... }` markers). */
114
+ export async function reportCommandResult(
115
+ requestId: string,
116
+ ok: boolean,
117
+ error?: string,
118
+ data?: Record<string, unknown>,
119
+ waitForCaller = false,
120
+ ): Promise<void> {
121
+ const payload = {
122
+ _requestId: requestId,
123
+ _clientId: EDITOR_CLIENT_ID,
124
+ ok,
125
+ error,
126
+ data,
127
+ };
128
+ if (waitForCaller) await sendCommandResultControl(requestId, payload);
129
+ else await sendControl('command-result', payload);
130
+ }
131
+
132
+ export interface GameplayRecordingSink {
133
+ id: string;
134
+ path: string;
135
+ format: 'composite-webm' | 'canvas-dom';
136
+ /** Directory containing `manifest.json`, `events.json`, and interned assets
137
+ * for a canvas + DOM recording. Absent for a composite WebM. */
138
+ replayPath: string | null;
139
+ /** True when this sink is the ROTATING unnamed file — the next recording
140
+ * overwrites it. False for a caller-named keepsake. */
141
+ rotates: boolean;
142
+ /** The `logs/play-*.jsonl` this project's live play run is writing, or
143
+ * `null` when nothing is logging. Its event timestamps are what map an
144
+ * event to an offset in the clip, so it travels WITH the clip's identity
145
+ * rather than being looked up separately later. */
146
+ logFile: string | null;
147
+ }
148
+
149
+ async function recordingResponse<T>(response: Response, action: string): Promise<T> {
150
+ // `.json().catch(() => ({}))` under a page fallback produced an OK-looking
151
+ // empty sink: `start` handed back a sink with no id, and every chunk after it
152
+ // posted into nothing while the recorder showed a recording in progress.
153
+ assertEditorServerAnswered(response, `gameplay recording ${action} failed`);
154
+ const body = (await response.json().catch(() => ({}))) as { error?: unknown } & T;
155
+ if (!response.ok) {
156
+ throw new Error(
157
+ `gameplay recording ${action} failed: ${typeof body.error === 'string' ? body.error : `HTTP ${response.status}`}`,
158
+ );
159
+ }
160
+ return body;
161
+ }
162
+
163
+ /** Open the server-owned, project-scoped WebM sink. Video bytes never ride the
164
+ * JSON command relay: a long QA playthrough must not hit its 50 MiB ceiling. */
165
+ export async function beginGameplayRecordingSink(
166
+ input: {
167
+ startedAt: string;
168
+ mimeType: string;
169
+ format?: 'composite-webm' | 'canvas-dom';
170
+ /** Fixed-step exports do not use the session's wall-clock playback timeline. */
171
+ purpose?: 'export';
172
+ /** During Play, `null` names the clip after the Gameplay Session; outside
173
+ * one it falls back to `play-latest.webm`. A name takes a keepsake path. */
174
+ name?: string | null;
175
+ },
176
+ signal?: AbortSignal,
177
+ ): Promise<GameplayRecordingSink> {
178
+ const response = await fetch(`${BASE}/recording/start`, {
179
+ ...(signal ? { signal } : {}),
180
+ method: 'POST',
181
+ headers: { 'content-type': 'application/json' },
182
+ body: JSON.stringify(input),
183
+ });
184
+ return recordingResponse<GameplayRecordingSink>(response, 'start');
185
+ }
186
+
187
+ /** Append an ordered batch of standard rrweb events. */
188
+ export async function appendGameplayRecordingDomEvents(
189
+ sink: GameplayRecordingSink,
190
+ sequence: number,
191
+ eventsJson: Blob,
192
+ signal?: AbortSignal,
193
+ ): Promise<void> {
194
+ const query = new URLSearchParams({ id: sink.id, sequence: String(sequence) });
195
+ const response = await fetch(`${BASE}/recording/dom?${query}`, {
196
+ ...(signal ? { signal } : {}),
197
+ method: 'POST',
198
+ // This is a streamed file body. Labeling it application/json lets the
199
+ // server's ordinary JSON middleware consume it before the route can apply
200
+ // its own byte bound, ordering, and append semantics.
201
+ headers: { 'content-type': 'application/octet-stream' },
202
+ body: eventsJson,
203
+ });
204
+ await recordingResponse<Record<string, never>>(response, 'DOM event upload');
205
+ }
206
+
207
+ /** Store one image interned out of the rrweb event stream. */
208
+ export async function appendGameplayRecordingAsset(
209
+ sink: GameplayRecordingSink,
210
+ name: string,
211
+ asset: Blob,
212
+ signal?: AbortSignal,
213
+ ): Promise<void> {
214
+ const query = new URLSearchParams({ id: sink.id, name });
215
+ const response = await fetch(`${BASE}/recording/asset?${query}`, {
216
+ ...(signal ? { signal } : {}),
217
+ method: 'POST',
218
+ headers: { 'content-type': asset.type || 'application/octet-stream' },
219
+ body: asset,
220
+ });
221
+ await recordingResponse<Record<string, never>>(response, 'replay asset upload');
222
+ }
223
+
224
+ /** Append one ordered MediaRecorder chunk to the open WebM. */
225
+ export async function appendGameplayRecordingChunk(
226
+ sink: GameplayRecordingSink,
227
+ sequence: number,
228
+ chunk: Blob,
229
+ signal?: AbortSignal,
230
+ ): Promise<void> {
231
+ const query = new URLSearchParams({ id: sink.id, sequence: String(sequence) });
232
+ const response = await fetch(`${BASE}/recording/chunk?${query}`, {
233
+ ...(signal ? { signal } : {}),
234
+ method: 'POST',
235
+ headers: { 'content-type': 'application/octet-stream' },
236
+ body: chunk,
237
+ });
238
+ await recordingResponse<Record<string, never>>(response, 'chunk upload');
239
+ }
240
+
241
+ export async function finishGameplayRecordingSink(
242
+ sink: GameplayRecordingSink,
243
+ /** What ended it — journalled verbatim beside the file it produced. */
244
+ reason?: string | null,
245
+ signal?: AbortSignal,
246
+ replay?: Record<string, unknown> | null,
247
+ ): Promise<void> {
248
+ const response = await fetch(`${BASE}/recording/finish`, {
249
+ ...(signal ? { signal } : {}),
250
+ method: 'POST',
251
+ headers: { 'content-type': 'application/json' },
252
+ body: JSON.stringify({ id: sink.id, reason: reason ?? null, replay: replay ?? null }),
253
+ });
254
+ await recordingResponse<Record<string, never>>(response, 'finish');
255
+ }
256
+
257
+ /** Deliberately NOT read through `editor-server-response.ts`: this is the
258
+ * teardown leg, called only when a recording is already being abandoned, and
259
+ * its `.catch(() => undefined)` is the contract — there is no caller left to
260
+ * report to, so asserting could only turn a silent no-op into a swallowed
261
+ * throw. */
262
+ export async function abortGameplayRecordingSink(sink: GameplayRecordingSink): Promise<void> {
263
+ await fetch(`${BASE}/recording/abort`, {
264
+ method: 'POST',
265
+ headers: { 'content-type': 'application/json' },
266
+ body: JSON.stringify({ id: sink.id }),
267
+ }).catch(() => undefined);
268
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The two shared settings layers over the wire (`server/routes/settings.ts`):
3
+ * `~/.vgai/settings.json` (user) and `<project>/.vgai/settings.json`
4
+ * (project), both files the editor server owns.
5
+ */
6
+ import type { EditorSettings } from '@volter/editor-project/settings/schema';
7
+ import { assertEditorServerResponse, editorServerJson } from '../editor-server-response';
8
+ import { BASE } from './base';
9
+
10
+ export type SettingsLayer = 'user' | 'project';
11
+
12
+ export interface SettingsLayerRead {
13
+ readonly settings: EditorSettings;
14
+ /** Problems with the stored document, spelled for the person who owns it. */
15
+ readonly issues: readonly string[];
16
+ /** Where the layer lives, for the issue report. */
17
+ readonly path: string | null;
18
+ }
19
+
20
+ export async function loadSettingsLayer(layer: SettingsLayer): Promise<SettingsLayerRead> {
21
+ const res = await fetch(`${BASE}/settings/${layer}`);
22
+ return editorServerJson<SettingsLayerRead>(res, `Could not read ${layer} settings`);
23
+ }
24
+
25
+ export async function saveSettingsLayer(
26
+ layer: SettingsLayer,
27
+ settings: EditorSettings,
28
+ ): Promise<void> {
29
+ const body = JSON.stringify(settings, null, 2);
30
+ const res = await fetch(`${BASE}/settings/${layer}`, {
31
+ method: 'POST',
32
+ headers: { 'Content-Type': 'application/json' },
33
+ body,
34
+ });
35
+ assertEditorServerResponse(res, `Could not save ${layer} settings`);
36
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Custom palette documents over the wire (`server/routes/themes.ts`): one
3
+ * JSON file per theme under `~/.vgai/themes/` (user) and
4
+ * `<project>/.vgai/themes/` (project) — both files the editor server owns.
5
+ */
6
+ import { assertEditorServerResponse, editorServerJson } from '../editor-server-response';
7
+ import { BASE } from './base';
8
+ import type { SettingsLayer } from './settings';
9
+
10
+ export interface ThemeDocumentRead {
11
+ readonly id: string;
12
+ readonly path: string;
13
+ readonly document: unknown;
14
+ }
15
+
16
+ export interface ThemeLayerRead {
17
+ readonly documents: readonly ThemeDocumentRead[];
18
+ /** Files that could not be read as JSON, spelled by path. */
19
+ readonly issues: readonly string[];
20
+ }
21
+
22
+ export async function listThemeDocuments(layer: SettingsLayer): Promise<ThemeLayerRead> {
23
+ const res = await fetch(`${BASE}/themes/${layer}`);
24
+ return editorServerJson<ThemeLayerRead>(res, `Could not list ${layer} themes`);
25
+ }
26
+
27
+ export async function saveThemeDocument(
28
+ layer: SettingsLayer,
29
+ id: string,
30
+ document: unknown,
31
+ ): Promise<void> {
32
+ const res = await fetch(`${BASE}/themes/${layer}`, {
33
+ method: 'POST',
34
+ headers: { 'Content-Type': 'application/json' },
35
+ body: JSON.stringify({ id, document }),
36
+ });
37
+ assertEditorServerResponse(res, `Could not save the ${layer} theme ${id}`);
38
+ }
39
+
40
+ export async function deleteThemeDocument(layer: SettingsLayer, id: string): Promise<void> {
41
+ const res = await fetch(`${BASE}/themes/${layer}?id=${encodeURIComponent(id)}`, {
42
+ method: 'DELETE',
43
+ });
44
+ assertEditorServerResponse(res, `Could not delete the ${layer} theme ${id}`);
45
+ }