@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,112 @@
1
+ /**
2
+ * WHICH PRODUCT THIS SESSION IS SERVING — the session's half of the resolution
3
+ * the CLI already did.
4
+ *
5
+ * `vgai edit` resolves the product from the project's own dependencies
6
+ * (`@volter/editor-sdk/session/product-locator`) so a bad or missing declaration
7
+ * is named before a server exists, then hands the directory over in
8
+ * `VGAI_PRODUCT_DIR`, beside `VGAI_WORKBENCH_DIR`. The session reads it back
9
+ * for the two things only it can do: SERVE the product's entry through
10
+ * `/__editor/served-modules`, and REPORT it (`EditorState.product`, printed by
11
+ * `vgai status` on the workbench's line) — a process reports what it is running.
12
+ *
13
+ * A session started without the variable resolves from the project itself
14
+ * rather than guessing, so `npx tsx packages/editor/server/dev.ts` by hand
15
+ * behaves the same as a CLI launch and fails with the same sentence.
16
+ */
17
+ import { existsSync, readFileSync } from 'node:fs';
18
+ import { createRequire } from 'node:module';
19
+ import { dirname, join } from 'node:path';
20
+ import { pathToFileURL } from 'node:url';
21
+ import {
22
+ productComposedPackages as composedPackages,
23
+ type ProductIdentity,
24
+ readProductManifest,
25
+ resolveProductForProject,
26
+ } from '@volter/editor-sdk/session/product-locator';
27
+
28
+ /** The product directory the CLI resolved and handed over. */
29
+ export const PRODUCT_DIR_ENV = 'VGAI_PRODUCT_DIR';
30
+
31
+ /**
32
+ * The product this session serves, or `null` when there is none to find — a
33
+ * session with no project open yet, or one whose project declares none. The
34
+ * served-modules door turns that `null` into its own refusal, naming the
35
+ * install line, rather than serving nothing silently.
36
+ */
37
+ export function sessionProduct(projectPath: string | null): ProductIdentity | null {
38
+ const handed = process.env[PRODUCT_DIR_ENV];
39
+ if (handed !== undefined && handed !== '' && existsSync(handed)) {
40
+ const product = readProductManifest(handed);
41
+ if (product !== null) return product;
42
+ }
43
+ if (projectPath === null) return null;
44
+ try {
45
+ return resolveProductForProject(projectPath);
46
+ } catch {
47
+ // The refusal belongs to the door that was asked, not to this read: the CLI
48
+ // already prints it at launch, and `served-modules` prints it to the frame.
49
+ return null;
50
+ }
51
+ }
52
+
53
+ /** `resolveProductForProject` — the same resolution, refusal and all, for the
54
+ * door that must say why. `productComposedPackages` — what that product
55
+ * mounts, read through the manifest mirror the estate gate keeps equal to the
56
+ * composition in its entry. */
57
+ export {
58
+ productComposedPackages,
59
+ resolveProductForProject,
60
+ } from '@volter/editor-sdk/session/product-locator';
61
+
62
+ /**
63
+ * EVERY CONTRIBUTION MODULE THE PRODUCT COMPOSES, as absolute files — what
64
+ * Vite's dependency crawl has to be HANDED, because it cannot walk to them.
65
+ *
66
+ * The product names a package as `vgai:contributions/<name>`, and that module
67
+ * is synthesized (`vite-plugin-product-contributions.ts`): it hangs off no file
68
+ * on disk, so `optimizeDeps`' esbuild scanner never reaches the `import()` rows
69
+ * inside it. `vite-plugin-module-doorways.ts`'s header records the same failure
70
+ * class from the other synthesized module and the same cure — read the entries
71
+ * out of the SAME declaration the browser is served, rather than letting the
72
+ * optimizer discover them when a lane first mounts.
73
+ *
74
+ * MEASURED 2026-09-21 on a `--template game` scaffold, before this existed: the
75
+ * boot pass prebundled the kit's own graph, the game editor's five packages
76
+ * then dragged in `storybook/internal/preview-api`, `storybook/internal/csf`,
77
+ * `@gltf-transform/{core,extensions,functions}` and `axe-core` as their
78
+ * contributions loaded, and Vite answered with `optimized dependencies changed.
79
+ * reloading` — a hard reload of the one tab, mid-boot, which drops the
80
+ * session's editor and every command with it.
81
+ */
82
+ export function productContributionFiles(product: ProductIdentity): string[] {
83
+ const resolveFrom = createRequire(pathToFileURL(join(product.dir, 'package.json')));
84
+ const files: string[] = [];
85
+ for (const name of composedPackages(product)) {
86
+ let manifestPath: string;
87
+ try {
88
+ manifestPath = resolveFrom.resolve(`${name}/package.json`);
89
+ } catch {
90
+ continue;
91
+ }
92
+ let declared: unknown;
93
+ try {
94
+ declared = (JSON.parse(readFileSync(manifestPath, 'utf8')) as ContributingManifest).vgai
95
+ ?.contributions;
96
+ } catch {
97
+ continue;
98
+ }
99
+ if (!Array.isArray(declared)) continue;
100
+ const dir = dirname(manifestPath);
101
+ for (const entry of declared) {
102
+ if (typeof entry !== 'string') continue;
103
+ const file = join(dir, entry);
104
+ if (existsSync(file)) files.push(file);
105
+ }
106
+ }
107
+ return files;
108
+ }
109
+
110
+ interface ContributingManifest {
111
+ vgai?: { contributions?: unknown };
112
+ }
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Editor session registry — the file-backed ledger of live editor dev servers.
3
+ * This module is the WRITER (dev.ts registers on listen, re-registers on
4
+ * project switch, unregisters on shutdown). The FORMAT — entry shape, guards,
5
+ * path, liveness-filtered read — lives once in `@vgai/sdk`'s
6
+ * `session-registry-format`, imported by every reader (this file, the CLI,
7
+ * and both SDK transports) instead of copied.
8
+ *
9
+ * Entries are best-effort — every reader must PID-liveness-filter (a crashed
10
+ * server can't unregister itself), and writers sweep dead entries on write.
11
+ */
12
+
13
+ import {
14
+ EDITOR_SESSIONS_REGISTRY_FILE,
15
+ type EditorSessionEntry as EditorSession,
16
+ isEditorSessionEntry,
17
+ normalizeEditorSessionEntry,
18
+ pidAlive,
19
+ } from '@volter/editor-sdk/session/registry-format';
20
+
21
+ export type { EditorSessionEntry as EditorSession } from '@volter/editor-sdk/session/registry-format';
22
+ export { pidAlive } from '@volter/editor-sdk/session/registry-format';
23
+
24
+ import { randomBytes, randomUUID } from 'node:crypto';
25
+ import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
26
+ import { homedir } from 'node:os';
27
+ import { join } from 'node:path';
28
+ import { resolveWorktreeIdentity, type WorktreeIdentity } from './worktree-identity';
29
+
30
+ export type EditorSessionAnnouncement = Pick<
31
+ EditorSession,
32
+ 'project' | 'port' | 'pid' | 'startedAt'
33
+ >;
34
+
35
+ const PROCESS_SESSION_ID = randomUUID();
36
+ const PROCESS_CONTROL_SECRET = randomBytes(32).toString('base64url');
37
+
38
+ export function processSessionId(): string {
39
+ return PROCESS_SESSION_ID;
40
+ }
41
+
42
+ export function processControlSecret(): string {
43
+ return PROCESS_CONTROL_SECRET;
44
+ }
45
+
46
+ export function sessionIdentity(project: string | null): WorktreeIdentity | null {
47
+ return project === null ? null : resolveWorktreeIdentity(project);
48
+ }
49
+
50
+ export function materializeSession(
51
+ announcement: EditorSessionAnnouncement,
52
+ id: string = PROCESS_SESSION_ID,
53
+ ): EditorSession {
54
+ const identity = sessionIdentity(announcement.project);
55
+ return {
56
+ ...announcement,
57
+ sessionId: id,
58
+ controlSecret: PROCESS_CONTROL_SECRET,
59
+ repositoryId: identity?.repositoryId ?? null,
60
+ worktreeId: identity?.worktreeId ?? null,
61
+ worktreeRoot: identity?.worktreeRoot ?? null,
62
+ projectRelativePath: identity?.projectRelativePath ?? null,
63
+ branch: identity?.branch ?? null,
64
+ headCommit: identity?.headCommit ?? null,
65
+ baseCommit: identity?.baseCommit ?? null,
66
+ };
67
+ }
68
+
69
+ const REGISTRY_DIR = join(homedir(), '.vgai');
70
+ const REGISTRY_FILE = EDITOR_SESSIONS_REGISTRY_FILE;
71
+
72
+ export function sessionRegistryPath(): string {
73
+ return REGISTRY_FILE;
74
+ }
75
+
76
+ /**
77
+ * Is this dev server an EPHEMERAL PROBE rather than a session anyone owns?
78
+ *
79
+ * `vgai doctor` spawns a real dev server on the target folder for a few
80
+ * seconds and drives it with its own headless browser. It is not an editing
81
+ * session: nobody should be able to reuse it, `vgai close` should not list
82
+ * it, and — the defect this exists for (SimCity ingest dogfood, S-6) — it
83
+ * must not touch the project's `.vgai/session.json`, which belongs to
84
+ * whichever `vgai edit` session is actually serving that folder. The probe
85
+ * used to OVERWRITE that file at boot with its own throwaway port/pid and
86
+ * then DELETE it on exit, so a live session the user was watching became
87
+ * undiscoverable (`cat .vgai/session.json` → ENOENT) because they ran a
88
+ * read-only diagnostic against it.
89
+ *
90
+ * Same shape as `VGAI_NO_OPEN`: an env flag the spawning tool sets on the
91
+ * child, never a mode the server infers. `'0'` explicitly opts back in, so
92
+ * the variable can be cleared by value in an inherited environment.
93
+ */
94
+ export function isEphemeralSession(env: NodeJS.ProcessEnv = process.env): boolean {
95
+ const value = env['VGAI_EPHEMERAL_SESSION'];
96
+ return value !== undefined && value !== '' && value !== '0';
97
+ }
98
+
99
+ /**
100
+ * Does this dev server contribute to the PERSON's launcher memory
101
+ * (`~/.vgai/recent-projects.json`, read by the Projects hub and by the
102
+ * opt-in "Reopen last project on launch")?
103
+ *
104
+ * Recents is machine-local state that belongs to a
105
+ * HUMAN at a launcher — it is what the hub shows first and what reopen-last
106
+ * reaches for. Two kinds of dev server have no such human by construction and
107
+ * must therefore stay out of it:
108
+ *
109
+ * - an EPHEMERAL PROBE (`isEphemeralSession`, today `vgai doctor`), which is
110
+ * not an editing session at all; and
111
+ * - a HEADLESS session (`VGAI_NO_OPEN` — the CLI's `--no-open`), which
112
+ * maintains no browser tab whatsoever: CI, headless harnesses, and every
113
+ * background-agent session. Measured: an agent's transient session wrote
114
+ * its scratchpad project into the owner's Recents, and the owner's next
115
+ * launcher boot reached for it.
116
+ *
117
+ * The read is the same truthiness `dev.ts`/`packaged.ts` already use for
118
+ * `tabBijection.enabled`, so "this session maintains a tab" and "this session
119
+ * is someone's launcher memory" can never disagree.
120
+ */
121
+ export function writesRecentProjects(env: NodeJS.ProcessEnv = process.env): boolean {
122
+ if (isEphemeralSession(env)) return false;
123
+ return !env['VGAI_NO_OPEN'];
124
+ }
125
+
126
+ /** All recorded sessions, unvalidated beyond shape (callers liveness-filter). */
127
+ export function readSessions(): EditorSession[] {
128
+ try {
129
+ const raw: unknown = JSON.parse(readFileSync(REGISTRY_FILE, 'utf8'));
130
+ return Array.isArray(raw)
131
+ ? raw.filter(isEditorSessionEntry).map(normalizeEditorSessionEntry)
132
+ : [];
133
+ } catch {
134
+ return [];
135
+ }
136
+ }
137
+
138
+ /** Sessions whose server process is still alive. */
139
+ export function liveSessions(): EditorSession[] {
140
+ return readSessions().filter((s) => pidAlive(s.pid));
141
+ }
142
+
143
+ /**
144
+ * Atomic registry replace: write a private temp file, then rename() it over
145
+ * the registry. rename(2) is atomic on POSIX (and effectively so on NTFS), so
146
+ * a concurrent reader always parses either the complete old array or the
147
+ * complete new one — never a torn/truncated file. Torn reads are not
148
+ * hypothetical: `readSessions()` maps ANY parse failure to `[]`, so a
149
+ * reader-that-then-writes (register/unregister — which now runs on every
150
+ * dev-server source-change restart) that catches another writer mid-truncate
151
+ * would persist that empty view and silently wipe every other live session's
152
+ * entry. Reproduced live 2026-07-25: two concurrent restart-churn processes
153
+ * emptied a registry seeded with three entries whose PIDs were still alive —
154
+ * the wiped sessions kept running but became invisible to `vgai
155
+ * edit`/`sessions`/`close`, which is the "new editors starting over and over
156
+ * while strays accumulate" failure mode.
157
+ */
158
+ function replaceRegistry(sessions: EditorSession[]): void {
159
+ const tmp = `${REGISTRY_FILE}.${process.pid}.tmp`;
160
+ writeFileSync(tmp, `${JSON.stringify(sessions, null, 2)}\n`, { mode: 0o600 });
161
+ renameSync(tmp, REGISTRY_FILE);
162
+ // Owner-only is the intent; a filesystem without modes (a browser runtime)
163
+ // keeps the file and skips the bit.
164
+ try {
165
+ chmodSync(REGISTRY_FILE, 0o600);
166
+ } catch {
167
+ /* no modes here */
168
+ }
169
+ }
170
+
171
+ /**
172
+ * A registry record whose pid is not alive is HISTORY, not identity.
173
+ *
174
+ * A dead record must
175
+ * never contribute a project — or anything else — to the port it used to
176
+ * hold, and no live server may inherit one. The registry is a ledger of what
177
+ * IS running, so every write prunes what is not; a reader that forgets to
178
+ * liveness-filter can then only ever see stale entries this process has not
179
+ * swept yet, never entries the registry deliberately kept.
180
+ *
181
+ * `isAlive` is injectable so the rule is testable against fabricated pids
182
+ * without spawning (or killing) real processes.
183
+ */
184
+ export function pruneDeadSessions(
185
+ sessions: readonly EditorSession[],
186
+ isAlive: (pid: number) => boolean = pidAlive,
187
+ ): EditorSession[] {
188
+ return sessions.filter((s) => isAlive(s.pid));
189
+ }
190
+
191
+ /**
192
+ * The registry as it must look once `incoming` has taken its port: every dead
193
+ * record gone, the previous claim on this pid or this port replaced, and
194
+ * `incoming` appended. Pure, for the same reason as `pruneDeadSessions`.
195
+ */
196
+ export function registryAfterRegistration(
197
+ sessions: readonly EditorSession[],
198
+ incoming: EditorSession,
199
+ isAlive: (pid: number) => boolean = pidAlive,
200
+ ): EditorSession[] {
201
+ const rest = pruneDeadSessions(sessions, isAlive).filter(
202
+ (s) => s.pid !== incoming.pid && s.port !== incoming.port,
203
+ );
204
+ return [...rest, incoming];
205
+ }
206
+
207
+ /**
208
+ * Record (or refresh) this process's session. Sweeps dead entries and any
209
+ * stale claim on the same port while it's here.
210
+ */
211
+ export function registerSession(announcement: EditorSessionAnnouncement): void {
212
+ try {
213
+ mkdirSync(REGISTRY_DIR, { recursive: true });
214
+ replaceRegistry(registryAfterRegistration(readSessions(), materializeSession(announcement)));
215
+ } catch {
216
+ // Registry is best-effort — never let bookkeeping kill the server.
217
+ }
218
+ }
219
+
220
+ export function unregisterSession(pid: number): void {
221
+ try {
222
+ // Same rule on the way out: this process's record goes, and so does every
223
+ // record whose server is already gone. Leaving those behind is what lets a
224
+ // dead entry outlive the server it described and keep answering "which
225
+ // project is on port N?" long after nothing is.
226
+ replaceRegistry(pruneDeadSessions(readSessions().filter((s) => s.pid !== pid)));
227
+ } catch {
228
+ // Best-effort (see registerSession).
229
+ }
230
+ }
@@ -0,0 +1,138 @@
1
+ import { createHmac, timingSafeEqual } from 'node:crypto';
2
+
3
+ export interface ShareGatewayClaims {
4
+ participantId: string;
5
+ invitationId: string;
6
+ credentialId: string;
7
+ role: 'viewer' | 'commenter' | 'tester' | 'editor' | 'terminal';
8
+ account: { id: string; email: string; name?: string };
9
+ }
10
+
11
+ const CLAIM_HEADERS = [
12
+ 'x-vgai-share-participant-id',
13
+ 'x-vgai-share-invitation-id',
14
+ 'x-vgai-share-credential-id',
15
+ 'x-vgai-share-role',
16
+ 'x-vgai-share-account-id',
17
+ 'x-vgai-share-account-email',
18
+ 'x-vgai-share-account-name',
19
+ 'x-vgai-share-signed-at',
20
+ 'x-vgai-share-signature',
21
+ ] as const;
22
+
23
+ export const shareClaimHeaders: readonly string[] = CLAIM_HEADERS;
24
+
25
+ function payload(
26
+ method: string,
27
+ url: string,
28
+ claims: ShareGatewayClaims,
29
+ signedAt: string,
30
+ ): string {
31
+ return [
32
+ method.toUpperCase(),
33
+ url,
34
+ claims.participantId,
35
+ claims.invitationId,
36
+ claims.credentialId,
37
+ claims.role,
38
+ claims.account.id,
39
+ claims.account.email,
40
+ claims.account.name ?? '',
41
+ signedAt,
42
+ ].join('\n');
43
+ }
44
+
45
+ function signature(secret: string, content: string): string {
46
+ return createHmac('sha256', secret).update(content).digest('base64url');
47
+ }
48
+
49
+ export function signedShareClaimHeaders(
50
+ secret: string,
51
+ method: string,
52
+ url: string,
53
+ claims: ShareGatewayClaims,
54
+ now: number = Date.now(),
55
+ ): Record<string, string> {
56
+ const signedAt = String(now);
57
+ return {
58
+ 'x-vgai-share-participant-id': claims.participantId,
59
+ 'x-vgai-share-invitation-id': claims.invitationId,
60
+ 'x-vgai-share-credential-id': claims.credentialId,
61
+ 'x-vgai-share-role': claims.role,
62
+ 'x-vgai-share-account-id': claims.account.id,
63
+ 'x-vgai-share-account-email': claims.account.email,
64
+ ...(claims.account.name
65
+ ? { 'x-vgai-share-account-name': encodeURIComponent(claims.account.name) }
66
+ : {}),
67
+ 'x-vgai-share-signed-at': signedAt,
68
+ 'x-vgai-share-signature': signature(secret, payload(method, url, claims, signedAt)),
69
+ };
70
+ }
71
+
72
+ export function verifyShareClaimHeaders(
73
+ secret: string,
74
+ method: string,
75
+ url: string,
76
+ read: (name: string) => string | undefined,
77
+ now: number = Date.now(),
78
+ ): ShareGatewayClaims | null {
79
+ const values = Object.fromEntries(CLAIM_HEADERS.map((name) => [name, read(name)?.trim()]));
80
+ const any = CLAIM_HEADERS.some((name) => values[name]);
81
+ if (!any) return null;
82
+ const participantId = values['x-vgai-share-participant-id'];
83
+ const invitationId = values['x-vgai-share-invitation-id'];
84
+ const credentialId = values['x-vgai-share-credential-id'];
85
+ const role = values['x-vgai-share-role'];
86
+ const accountId = values['x-vgai-share-account-id'];
87
+ const accountEmail = values['x-vgai-share-account-email'];
88
+ const encodedName = values['x-vgai-share-account-name'];
89
+ const signedAt = values['x-vgai-share-signed-at'];
90
+ const supplied = values['x-vgai-share-signature'];
91
+ if (
92
+ !participantId ||
93
+ participantId.length > 200 ||
94
+ !invitationId ||
95
+ invitationId.length > 200 ||
96
+ !credentialId ||
97
+ credentialId.length > 200 ||
98
+ !role ||
99
+ !['viewer', 'commenter', 'tester', 'editor', 'terminal'].includes(role) ||
100
+ !accountId ||
101
+ accountId.length > 200 ||
102
+ !accountEmail ||
103
+ accountEmail.length > 320 ||
104
+ !signedAt ||
105
+ !supplied
106
+ )
107
+ throw new Error('Invalid share gateway claims.');
108
+ const signedAtMs = Number(signedAt);
109
+ if (!Number.isSafeInteger(signedAtMs) || Math.abs(now - signedAtMs) > 30_000) {
110
+ throw new Error('Expired share gateway claims.');
111
+ }
112
+ let name: string | undefined;
113
+ if (encodedName) {
114
+ try {
115
+ name = decodeURIComponent(encodedName);
116
+ } catch {
117
+ throw new Error('Invalid share gateway claims.');
118
+ }
119
+ if (name.length > 200) throw new Error('Invalid share gateway claims.');
120
+ }
121
+ const claims: ShareGatewayClaims = {
122
+ participantId,
123
+ invitationId,
124
+ credentialId,
125
+ role: role as ShareGatewayClaims['role'],
126
+ account: { id: accountId, email: accountEmail, ...(name ? { name } : {}) },
127
+ };
128
+ const expected = signature(secret, payload(method, url, claims, signedAt));
129
+ const actualBuffer = Buffer.from(supplied);
130
+ const expectedBuffer = Buffer.from(expected);
131
+ if (
132
+ actualBuffer.length !== expectedBuffer.length ||
133
+ !timingSafeEqual(actualBuffer, expectedBuffer)
134
+ ) {
135
+ throw new Error('Invalid share gateway signature.');
136
+ }
137
+ return claims;
138
+ }