@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,123 @@
1
+ import { type ChildProcess, spawn } from 'node:child_process';
2
+
3
+ export type ShareTunnelProvider = 'cloudflared' | 'ngrok';
4
+
5
+ export interface ShareTunnel {
6
+ child: ChildProcess;
7
+ publicUrl: string;
8
+ }
9
+
10
+ export type ShareTunnelStarter = (port: number) => Promise<ShareTunnel>;
11
+
12
+ function publicUrl(line: string, pattern: RegExp): string | null {
13
+ const direct = line.match(pattern)?.[0];
14
+ if (direct) return direct;
15
+ try {
16
+ const parsed = JSON.parse(line) as Record<string, unknown>;
17
+ for (const value of Object.values(parsed)) {
18
+ if (typeof value !== 'string') continue;
19
+ const match = value.match(pattern)?.[0];
20
+ if (match) return match;
21
+ }
22
+ } catch {
23
+ // Human-readable output is handled by the direct expression.
24
+ }
25
+ return null;
26
+ }
27
+
28
+ export function parseNgrokPublicUrl(line: string): string | null {
29
+ return publicUrl(line, /https:\/\/[a-zA-Z0-9.-]+\.ngrok(?:-free)?\.(?:app|dev)/);
30
+ }
31
+
32
+ export function parseCloudflaredPublicUrl(line: string): string | null {
33
+ return publicUrl(line, /https:\/\/[a-zA-Z0-9-]+\.trycloudflare\.com/);
34
+ }
35
+
36
+ function startTunnelProcess(input: {
37
+ provider: ShareTunnelProvider;
38
+ command: string;
39
+ args: string[];
40
+ parseUrl(line: string): string | null;
41
+ prerequisite: string;
42
+ }): Promise<ShareTunnel> {
43
+ const child = spawn(input.command, input.args, { stdio: ['ignore', 'pipe', 'pipe'] });
44
+ return new Promise<ShareTunnel>((resolveUrl, rejectUrl) => {
45
+ let settled = false;
46
+ let output = '';
47
+ const timer = setTimeout(() => {
48
+ if (settled) return;
49
+ settled = true;
50
+ child.kill('SIGTERM');
51
+ rejectUrl(
52
+ new Error(`${input.provider} did not publish a URL within 30 seconds.\n${output.trim()}`),
53
+ );
54
+ }, 30_000);
55
+ const inspect = (chunk: Buffer | string) => {
56
+ const text = chunk.toString();
57
+ output = `${output}${text}`.slice(-8_000);
58
+ for (const line of text.split(/\r?\n/)) {
59
+ const url = input.parseUrl(line);
60
+ if (!url || settled) continue;
61
+ settled = true;
62
+ clearTimeout(timer);
63
+ resolveUrl({ child, publicUrl: url });
64
+ return;
65
+ }
66
+ };
67
+ child.stdout?.on('data', inspect);
68
+ child.stderr?.on('data', inspect);
69
+ child.once('error', (error) => {
70
+ if (settled) return;
71
+ settled = true;
72
+ clearTimeout(timer);
73
+ rejectUrl(new Error(error.message.includes('ENOENT') ? input.prerequisite : error.message));
74
+ });
75
+ child.once('exit', (code) => {
76
+ if (settled) return;
77
+ settled = true;
78
+ clearTimeout(timer);
79
+ rejectUrl(
80
+ new Error(
81
+ `${input.provider} exited before publishing a URL (code ${code}).\n${output.trim()}`,
82
+ ),
83
+ );
84
+ });
85
+ });
86
+ }
87
+
88
+ export function startNgrokShareTunnel(port: number): Promise<ShareTunnel> {
89
+ return startTunnelProcess({
90
+ provider: 'ngrok',
91
+ command: 'ngrok',
92
+ args: ['http', `http://127.0.0.1:${port}`, '--log', 'stdout', '--log-format', 'json'],
93
+ parseUrl: parseNgrokPublicUrl,
94
+ prerequisite: 'ngrok is required for this share. Install and authenticate ngrok first.',
95
+ });
96
+ }
97
+
98
+ export function startCloudflaredShareTunnel(port: number): Promise<ShareTunnel> {
99
+ return startTunnelProcess({
100
+ provider: 'cloudflared',
101
+ command: 'cloudflared',
102
+ args: [
103
+ 'tunnel',
104
+ '--url',
105
+ `http://127.0.0.1:${port}`,
106
+ '--no-autoupdate',
107
+ // Quick Tunnels default to QUIC, which is commonly blocked on managed
108
+ // networks even when ordinary HTTPS works. HTTP/2 preserves the
109
+ // accountless path without requiring UDP egress.
110
+ '--protocol',
111
+ 'http2',
112
+ '--config',
113
+ process.platform === 'win32' ? 'NUL' : '/dev/null',
114
+ ],
115
+ parseUrl: parseCloudflaredPublicUrl,
116
+ prerequisite:
117
+ 'cloudflared is required for this share. Install cloudflared; Quick Tunnels need no Cloudflare account.',
118
+ });
119
+ }
120
+
121
+ export function shareTunnelStarter(provider: ShareTunnelProvider): ShareTunnelStarter {
122
+ return provider === 'cloudflared' ? startCloudflaredShareTunnel : startNgrokShareTunnel;
123
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Best-effort launch of an OS "open a URL" command (`open`, `cmd /c start`,
3
+ * `powershell.exe Start-Process`, `xdg-open`, …), extracted from
4
+ * `index.ts`'s `openBrowser` into its own module so it's unit-testable
5
+ * against a REAL spawned child (see `spawn-opener.test.ts`) without pulling
6
+ * in the whole CLI entry point.
7
+ */
8
+
9
+ import { type ChildProcess, spawn } from 'node:child_process';
10
+
11
+ /** Cap on how much of a failed opener's stderr we buffer before printing —
12
+ * enough for a real error message, small enough to never matter for a
13
+ * detached fire-and-forget child. */
14
+ export const OPENER_STDERR_CAP_BYTES = 2048;
15
+
16
+ /** An unref'd child's piped stderr only stays readable for as long as THIS
17
+ * process's event loop keeps ticking — normally guaranteed by the caller's
18
+ * verified-open poll (>=15s, see waitForVerifiedEditorOpen). Belt-and-
19
+ * suspenders bound so a genuinely long-lived/never-exiting opener can't
20
+ * hold the pipe (and this process) open indefinitely if the parent exits
21
+ * on its own first. */
22
+ export const OPENER_EXIT_WATCH_TIMEOUT_MS = 20_000;
23
+
24
+ /** Fire one open attempt, NAMING the failure instead of swallowing it.
25
+ * Two failure modes, both silent before this fix:
26
+ * - meteor-dodge dry-run friction #1: the powershell.exe hand-off died
27
+ * silently in a background shell — spawn launch failures arrive on the
28
+ * child's 'error' event, which nothing listened to.
29
+ * - run-3 dogfood friction #3: a child that LAUNCHES but exits nonzero
30
+ * (e.g. Start-Process itself failing inside powershell) was silent too —
31
+ * stdio was fully 'ignore'd and nothing checked the exit code.
32
+ * Still best-effort: a failure logs one line (stderr captured, capped, and
33
+ * included when available) and runs `fallback`, if given — never throws,
34
+ * never blocks. */
35
+ export function spawnOpener(cmd: string, cmdArgs: string[], fallback?: () => void): void {
36
+ let child: ChildProcess;
37
+ try {
38
+ child = spawn(cmd, cmdArgs, { stdio: ['ignore', 'ignore', 'pipe'], detached: true });
39
+ } catch (err) {
40
+ console.error(`vgai: auto-open via ${cmd} failed: ${(err as Error).message}`);
41
+ fallback?.();
42
+ return;
43
+ }
44
+
45
+ const stderrChunks: Buffer[] = [];
46
+ let stderrBytes = 0;
47
+ child.stderr?.on('data', (chunk: Buffer) => {
48
+ if (stderrBytes >= OPENER_STDERR_CAP_BYTES) return;
49
+ const remaining = OPENER_STDERR_CAP_BYTES - stderrBytes;
50
+ const slice = chunk.length > remaining ? chunk.subarray(0, remaining) : chunk;
51
+ stderrChunks.push(slice);
52
+ stderrBytes += slice.length;
53
+ });
54
+
55
+ child.on('error', (err) => {
56
+ console.error(`vgai: auto-open via ${cmd} failed to launch: ${err.message}`);
57
+ fallback?.();
58
+ });
59
+
60
+ child.on('exit', (code) => {
61
+ if (code !== null && code !== 0) {
62
+ const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();
63
+ console.error(`vgai: auto-open via ${cmd} exited ${code}: ${stderr}`);
64
+ fallback?.();
65
+ }
66
+ });
67
+
68
+ child.unref();
69
+
70
+ const pipeTimeout = setTimeout(() => {
71
+ child.stderr?.destroy();
72
+ }, OPENER_EXIT_WATCH_TIMEOUT_MS);
73
+ pipeTimeout.unref();
74
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * THE on-disk shape of `<project>/logs/play-*.jsonl` — one definition, shared
3
+ * by the writer (`editor-server.ts`'s `/__editor/log-session` +
4
+ * `/__editor/log-entries` handlers) and every reader (`play.log.*` here,
5
+ * `vgai status`'s play-error banner, the project Analytics utility).
6
+ *
7
+ * A play log is JSONL with TWO record kinds:
8
+ *
9
+ * 1. THE HEADER — always the FIRST line, written when the file is opened:
10
+ * `{"kind":"session","v":1,"session":…,"project":…,"run":…,"startedAt":…}`.
11
+ * This is where the run's IDENTITY lives, recorded ONCE. The alternative
12
+ * (stamping session/project onto every entry) pays the same constant
13
+ * thousands of times per run for facts that cannot change while the file
14
+ * is open — the file is opened by one session, for one project, at one
15
+ * instant.
16
+ * 2. ENTRIES — every later line: `{t, level, source?, sub?, msg, meta?,
17
+ * tick?, simT?, world?, simSpeed?}`. Only genuinely per-entry facts go
18
+ * here: `tick`/`simT` (the frame the line was written on), `simSpeed`
19
+ * (the live time scale, which an instrument can change mid-run) and
20
+ * `world` (the world the run is presenting, unknown until the roots
21
+ * mount — so the entries written during boot honestly carry none).
22
+ *
23
+ * A reader must SKIP the header when counting or listing entries
24
+ * (`asPlayLogHeader` is the one test), and must tolerate its ABSENCE: logs
25
+ * written before the header existed are still on disk in real projects, and
26
+ * "no header" means "this run's identity was never recorded", never an error.
27
+ */
28
+
29
+ /** `kind` value marking a play log's header line. */
30
+ export const PLAY_LOG_HEADER_KIND = 'session';
31
+
32
+ /** Bumped only when the on-disk record shapes change incompatibly. */
33
+ export const PLAY_LOG_FORMAT_VERSION = 1;
34
+
35
+ /** The run identity a play log carries on its first line. */
36
+ export interface PlayLogHeader {
37
+ readonly kind: typeof PLAY_LOG_HEADER_KIND;
38
+ readonly v: number;
39
+ /** The editor session that opened the file (`processSessionId()`) — the same
40
+ * id `vgai sessions` lists, so a log file names the session that wrote it. */
41
+ readonly session: string;
42
+ /** Absolute project root the session was serving. */
43
+ readonly project: string;
44
+ /** The run's slug (`vgai play --name <text>`), `null` for an unnamed run —
45
+ * the same slug that goes in the filename and the session journal. */
46
+ readonly run: string | null;
47
+ /** Wall-clock ms at which the file was opened. */
48
+ readonly startedAt: number;
49
+ }
50
+
51
+ /** The header line (newline included) for a run's identity. */
52
+ export function playLogHeaderLine(identity: Omit<PlayLogHeader, 'kind' | 'v'>): string {
53
+ const header: PlayLogHeader = {
54
+ kind: PLAY_LOG_HEADER_KIND,
55
+ v: PLAY_LOG_FORMAT_VERSION,
56
+ ...identity,
57
+ };
58
+ return `${JSON.stringify(header)}\n`;
59
+ }
60
+
61
+ /** The parsed header, or `null` when this record is an ordinary entry (or a
62
+ * header from an unreadable/older shape). Every reader's one header test. */
63
+ export function asPlayLogHeader(record: unknown): PlayLogHeader | null {
64
+ if (typeof record !== 'object' || record === null || Array.isArray(record)) return null;
65
+ const rec = record as Record<string, unknown>;
66
+ if (rec['kind'] !== PLAY_LOG_HEADER_KIND) return null;
67
+ if (typeof rec['session'] !== 'string' || typeof rec['project'] !== 'string') return null;
68
+ return {
69
+ kind: PLAY_LOG_HEADER_KIND,
70
+ v: typeof rec['v'] === 'number' ? rec['v'] : 0,
71
+ session: rec['session'],
72
+ project: rec['project'],
73
+ run: typeof rec['run'] === 'string' ? rec['run'] : null,
74
+ startedAt: typeof rec['startedAt'] === 'number' ? rec['startedAt'] : 0,
75
+ };
76
+ }
@@ -0,0 +1,199 @@
1
+ /**
2
+ * The Gameplay Session RECORD, as pure functions over the play log's text.
3
+ * The server derives the catalog from `logs/*.jsonl` on disk
4
+ * (`server/gameplay-sessions.ts`, which keeps its stat-keyed cache and fs
5
+ * wiring and calls in here); the functions themselves touch no filesystem, so
6
+ * the rules live in one place. They are subtle enough to fork badly — the
7
+ * torn live-append tail, the
8
+ * `ended` marker, the three-message recording lifecycle — which is why they
9
+ * live HERE and nowhere twice.
10
+ *
11
+ * Also home to the retention budgets, for the same reason: two copies of a
12
+ * byte budget is how two readers start keeping different histories.
13
+ */
14
+
15
+ import { asPlayLogHeader } from './log-format';
16
+
17
+ /** Structured logs are the durable Analytics source. At the current event
18
+ * density this keeps hundreds of substantial sessions, without allowing one
19
+ * project to grow forever. */
20
+ export const GAMEPLAY_SESSION_LOG_BUDGET_BYTES = 256 * 1024 * 1024;
21
+
22
+ /** Automatically named session clips are working evidence, not keepsakes.
23
+ * Two GiB provides a useful history while making long recordings pay their
24
+ * actual disk cost. Explicitly named recordings are outside this budget. */
25
+ export const GAMEPLAY_SESSION_CLIP_BUDGET_BYTES = 2 * 1024 * 1024 * 1024;
26
+
27
+ export interface GameplaySessionRecording {
28
+ readonly format: 'composite-webm' | 'canvas-dom';
29
+ readonly replay: string | null;
30
+ readonly file: string;
31
+ readonly url: string;
32
+ readonly startedAt: number | null;
33
+ readonly finalized: boolean;
34
+ readonly bytes: number | null;
35
+ }
36
+
37
+ export interface GameplaySessionRecord {
38
+ readonly id: string;
39
+ readonly run: string | null;
40
+ readonly status: 'live' | 'completed';
41
+ readonly startedAt: number;
42
+ readonly endedAt: number | null;
43
+ readonly durationMs: number;
44
+ readonly logFile: string;
45
+ readonly entries: readonly Record<string, unknown>[];
46
+ readonly recording: GameplaySessionRecording | null;
47
+ }
48
+
49
+ export interface ParsedGameplaySession {
50
+ readonly id: string;
51
+ readonly run: string | null;
52
+ readonly startedAt: number;
53
+ readonly endedAt: number | null;
54
+ readonly logFile: string;
55
+ readonly entries: readonly Record<string, unknown>[];
56
+ readonly recording: GameplaySessionRecording | null;
57
+ readonly fallbackEndedAt: number;
58
+ }
59
+
60
+ function numberField(value: unknown): number | null {
61
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
62
+ }
63
+
64
+ /** A bare filename — no path separators. The same refusal the server's
65
+ * `basename(file) !== file` check made, path-module-free. */
66
+ function isBareFilename(file: string): boolean {
67
+ return file.length > 0 && !file.includes('/') && !file.includes('\\');
68
+ }
69
+
70
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: this is a small single-pass reducer over three recording lifecycle messages.
71
+ function recordingEvent(
72
+ entries: readonly Record<string, unknown>[],
73
+ ): Omit<GameplaySessionRecording, 'url'> | null {
74
+ type RecordingState = Omit<GameplaySessionRecording, 'url'>;
75
+ let current: RecordingState | null = null;
76
+ for (const entry of entries) {
77
+ if (entry['source'] !== 'gameplay-recording') continue;
78
+ const meta = entry['meta'];
79
+ if (typeof meta !== 'object' || meta === null || Array.isArray(meta)) continue;
80
+ const fields = meta as Record<string, unknown>;
81
+ const file = fields['file'];
82
+ if (typeof file !== 'string' || !isBareFilename(file)) continue;
83
+ if (entry['msg'] === 'started') {
84
+ current = {
85
+ file,
86
+ format: fields['format'] === 'canvas-dom' ? 'canvas-dom' : 'composite-webm',
87
+ replay: null,
88
+ startedAt: numberField(fields['startedAt']),
89
+ finalized: false,
90
+ bytes: null,
91
+ };
92
+ } else if (entry['msg'] === 'finalized') {
93
+ const existing = current as RecordingState | null;
94
+ if (existing?.file === file) {
95
+ current = {
96
+ ...existing,
97
+ finalized: true,
98
+ bytes: numberField(fields['bytes']),
99
+ replay:
100
+ typeof fields['replay'] === 'string' && isBareFilename(fields['replay'])
101
+ ? fields['replay']
102
+ : null,
103
+ };
104
+ }
105
+ } else if (
106
+ (current as RecordingState | null)?.file === file &&
107
+ (entry['msg'] === 'aborted' || entry['msg'] === 'evicted')
108
+ ) {
109
+ current = null;
110
+ }
111
+ }
112
+ return current;
113
+ }
114
+
115
+ export interface ParsePlayLogOptions {
116
+ /** The log's bare filename, e.g. `play-2026-…-0001.jsonl`. */
117
+ readonly file: string;
118
+ /** What "ended" means when the log carries no `ended` marker (a crashed
119
+ * run): the file's own last-modified time on tiers that know it, or the
120
+ * read time otherwise. */
121
+ readonly fallbackEndedAt: number;
122
+ /** How this tier addresses the session's recording, when one survives the
123
+ * lifecycle reduce — the server serves a route, the browser has none. */
124
+ readonly recordingUrl: (sessionId: string, recordingFile: string) => string;
125
+ }
126
+
127
+ /**
128
+ * Parse one play log's raw text into the session record's parsed half, or
129
+ * `null` when the first line is not a play-log identity header (any other
130
+ * JSONL in `logs/` is not a session).
131
+ */
132
+ export function parsePlayLogText(
133
+ raw: string,
134
+ options: ParsePlayLogOptions,
135
+ ): ParsedGameplaySession | null {
136
+ const records: unknown[] = [];
137
+ for (const line of raw.split('\n')) {
138
+ if (line.trim() === '') continue;
139
+ try {
140
+ records.push(JSON.parse(line) as unknown);
141
+ } catch {
142
+ // A live append may expose a torn tail. Everything before it remains a
143
+ // valid session record and the next poll will pick up the completed row.
144
+ }
145
+ }
146
+ const header = asPlayLogHeader(records[0]);
147
+ if (!header) return null;
148
+ const entries = records
149
+ .slice(1)
150
+ .filter(
151
+ (value): value is Record<string, unknown> =>
152
+ typeof value === 'object' && value !== null && !Array.isArray(value),
153
+ );
154
+ const end = [...entries]
155
+ .reverse()
156
+ .find((entry) => entry['source'] === 'gameplay-session' && entry['msg'] === 'ended');
157
+ const endMeta =
158
+ typeof end?.['meta'] === 'object' && end['meta'] !== null && !Array.isArray(end['meta'])
159
+ ? (end['meta'] as Record<string, unknown>)
160
+ : null;
161
+ const recording = recordingEvent(entries);
162
+ const id = options.file.replace(/\.[^.]*$/, '');
163
+ return {
164
+ id,
165
+ run: header.run,
166
+ startedAt: header.startedAt,
167
+ endedAt: numberField(endMeta?.['endedAt']),
168
+ fallbackEndedAt: options.fallbackEndedAt,
169
+ logFile: `logs/${options.file}`,
170
+ entries,
171
+ recording: recording ? { ...recording, url: options.recordingUrl(id, recording.file) } : null,
172
+ };
173
+ }
174
+
175
+ /**
176
+ * Project a parsed session against the tier's live state: the active log (if
177
+ * this is it, the session is `live` and its edge is `now`) or the recorded /
178
+ * fallback end.
179
+ */
180
+ export function materializeGameplaySession(
181
+ parsed: ParsedGameplaySession,
182
+ options: { readonly activeLogBaseName: string | null; readonly now: number },
183
+ ): GameplaySessionRecord {
184
+ const active =
185
+ options.activeLogBaseName !== null && parsed.logFile === `logs/${options.activeLogBaseName}`;
186
+ const endedAt = active ? null : (parsed.endedAt ?? parsed.fallbackEndedAt);
187
+ const liveEdge = active ? options.now : (endedAt ?? parsed.fallbackEndedAt);
188
+ return {
189
+ id: parsed.id,
190
+ run: parsed.run,
191
+ status: active ? 'live' : 'completed',
192
+ startedAt: parsed.startedAt,
193
+ endedAt,
194
+ durationMs: Math.max(0, liveEdge - parsed.startedAt),
195
+ logFile: parsed.logFile,
196
+ entries: parsed.entries,
197
+ recording: parsed.recording,
198
+ };
199
+ }