@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,595 @@
1
+ /**
2
+ * `/__editor/worktrees/**` + `/__editor/repository-presence` — the worktree
3
+ * board: what checkouts this repository has, which of them an editor is
4
+ * serving, and the create / open / delegate / archive / stop verbs over them.
5
+ *
6
+ * Every route here is owner-local (`requireLocalOwner`): a worktree verb runs
7
+ * git and spawns editors on the owner's machine, so a shared session's
8
+ * participants never reach it.
9
+ */
10
+
11
+ import { execFile, execFileSync } from 'node:child_process';
12
+ import { randomUUID } from 'node:crypto';
13
+ import type { Request, Response } from 'express';
14
+ import type { EditorServerRouter } from '../editor-server';
15
+ import { createRepositoryPresenceReader } from '../repository-presence';
16
+ import { liveSessions } from '../session-registry';
17
+ import {
18
+ archiveRepositoryWorktree,
19
+ attachRepositoryPresence,
20
+ createRepositoryWorktree,
21
+ listRepositoryBranches,
22
+ listRepositoryWorktrees,
23
+ prepareRepositoryWorktree,
24
+ publicWorktreeSessionRefs,
25
+ vgaiCliLaunchCommand,
26
+ type WorktreeView,
27
+ worktreeEditorLaunchCommand,
28
+ } from '../worktree-management';
29
+ import type { RouteContext } from './context';
30
+
31
+ export function registerWorktreeRoutes(router: EditorServerRouter, ctx: RouteContext): void {
32
+ const { currentSessionIdentity, engineRoot, harnessChat, requireLocalOwner } = ctx;
33
+ /** Owned here: `/__editor/repository-presence` is its only reader. */
34
+ const readRepositoryPresence = createRepositoryPresenceReader();
35
+
36
+ const currentWorktrees = async (): Promise<WorktreeView[]> => {
37
+ if (ctx.projectRoot === engineRoot) throw new Error('Open a Git-backed project first.');
38
+ return listRepositoryWorktrees(ctx.projectRoot, publicWorktreeSessionRefs(liveSessions()));
39
+ };
40
+
41
+ /**
42
+ * What the editor knows about one isolated worktree's editor.
43
+ *
44
+ * `unknown` and `stopped` used to be the same answer, and so did `starting`
45
+ * and `crashed`:
46
+ *
47
+ * - a stopped Docker daemon made every record's state read `missing`, which
48
+ * `!== 'running'` mapped to `stopped` — a container the user must be told
49
+ * is UNINSPECTABLE was reported as a container we had looked at and found
50
+ * halted, which is exactly the reading a cleanup gesture must not act on.
51
+ * `docker-unavailable` is now its own health and every destructive
52
+ * affordance refuses on it.
53
+ * - a running container whose editor never answered the compatibility probe
54
+ * read `starting` for as long as it existed. A boot has a duration; past
55
+ * {@link ISOLATED_EDITOR_BOOT_BUDGET_MS} of an unanswered probe against a
56
+ * container Docker says is RUNNING, the honest word is `unhealthy`.
57
+ */
58
+ type IsolatedWorktreeHealth =
59
+ | 'healthy'
60
+ | 'starting'
61
+ | 'unhealthy'
62
+ | 'stopped'
63
+ | 'docker-unavailable';
64
+
65
+ /** How long a running container's editor may go unprobeable before
66
+ * `starting` becomes `unhealthy`. A cold isolated editor installs and boots
67
+ * its own graph, so this is generous; what it must not be is unbounded. */
68
+ const ISOLATED_EDITOR_BOOT_BUDGET_MS = 5 * 60_000;
69
+
70
+ interface IsolatedWorktreeView {
71
+ id: string;
72
+ repositoryId: string;
73
+ branch: string;
74
+ from: string;
75
+ editorPort: number;
76
+ createdAt: string;
77
+ exportedAt?: string;
78
+ exportedHead?: string;
79
+ state: string;
80
+ /** `{{.State.StartedAt}}` from the same inspect, or `null` when the
81
+ * container could not be inspected. What BOUNDS `starting`. */
82
+ startedAt: string | null;
83
+ egressPolicy: 'allowlist';
84
+ egressHosts: string[];
85
+ health: IsolatedWorktreeHealth;
86
+ limits: { cpus: number; memory: string; pids: number; workspace: string; assetCache: string };
87
+ }
88
+
89
+ const isolatedCli = (args: readonly string[]) =>
90
+ vgaiCliLaunchCommand({
91
+ engineRoot,
92
+ cwd: ctx.projectRoot,
93
+ args: ['isolate', ...args],
94
+ inheritedCliEntry: process.env['VGAI_CLI_ENTRY'],
95
+ });
96
+
97
+ const runIsolatedCli = async (args: readonly string[]): Promise<string> => {
98
+ const command = isolatedCli(args);
99
+ return await new Promise<string>((resolveOutput, rejectOutput) => {
100
+ execFile(
101
+ command.command,
102
+ command.args,
103
+ { cwd: command.cwd, maxBuffer: 8 * 1024 * 1024 },
104
+ (error, stdout, stderr) => {
105
+ if (error) {
106
+ rejectOutput(new Error(stderr.trim() || stdout.trim() || error.message));
107
+ return;
108
+ }
109
+ resolveOutput(stdout.trim());
110
+ },
111
+ );
112
+ });
113
+ };
114
+
115
+ const currentIsolatedWorktrees = async (): Promise<IsolatedWorktreeView[]> => {
116
+ const identity = currentSessionIdentity();
117
+ if (!identity?.repositoryId) return [];
118
+ const command = isolatedCli(['list', '--json']);
119
+ const output = execFileSync(command.command, command.args, {
120
+ cwd: command.cwd,
121
+ encoding: 'utf8',
122
+ stdio: ['ignore', 'pipe', 'pipe'],
123
+ maxBuffer: 8 * 1024 * 1024,
124
+ });
125
+ const rows = JSON.parse(output) as unknown;
126
+ if (!Array.isArray(rows)) throw new Error('The isolated-worktree registry is malformed.');
127
+ const safeRows = rows.flatMap((raw): Omit<IsolatedWorktreeView, 'health'>[] => {
128
+ if (!raw || typeof raw !== 'object') return [];
129
+ const row = raw as Record<string, unknown>;
130
+ const limits = row['limits'];
131
+ if (
132
+ row['repositoryId'] !== identity.repositoryId ||
133
+ typeof row['id'] !== 'string' ||
134
+ typeof row['branch'] !== 'string' ||
135
+ typeof row['from'] !== 'string' ||
136
+ typeof row['editorPort'] !== 'number' ||
137
+ typeof row['createdAt'] !== 'string' ||
138
+ typeof row['state'] !== 'string' ||
139
+ !Array.isArray(row['egressHosts']) ||
140
+ !row['egressHosts'].every((host) => typeof host === 'string') ||
141
+ !limits ||
142
+ typeof limits !== 'object'
143
+ ) {
144
+ return [];
145
+ }
146
+ const limitRecord = limits as Record<string, unknown>;
147
+ if (
148
+ typeof limitRecord['cpus'] !== 'number' ||
149
+ typeof limitRecord['memory'] !== 'string' ||
150
+ typeof limitRecord['pids'] !== 'number' ||
151
+ typeof limitRecord['workspace'] !== 'string' ||
152
+ typeof limitRecord['assetCache'] !== 'string'
153
+ ) {
154
+ return [];
155
+ }
156
+ return [
157
+ {
158
+ id: row['id'],
159
+ repositoryId: row['repositoryId'],
160
+ branch: row['branch'],
161
+ from: row['from'],
162
+ editorPort: row['editorPort'],
163
+ createdAt: row['createdAt'],
164
+ state: row['state'],
165
+ startedAt: typeof row['startedAt'] === 'string' ? row['startedAt'] : null,
166
+ egressPolicy: 'allowlist',
167
+ egressHosts: [...row['egressHosts']],
168
+ ...(typeof row['exportedAt'] === 'string' ? { exportedAt: row['exportedAt'] } : {}),
169
+ ...(typeof row['exportedHead'] === 'string' ? { exportedHead: row['exportedHead'] } : {}),
170
+ limits: {
171
+ cpus: limitRecord['cpus'],
172
+ memory: limitRecord['memory'],
173
+ pids: limitRecord['pids'],
174
+ workspace: limitRecord['workspace'],
175
+ assetCache: limitRecord['assetCache'],
176
+ },
177
+ },
178
+ ];
179
+ });
180
+ return await Promise.all(
181
+ safeRows.map(async (row): Promise<IsolatedWorktreeView> => {
182
+ if (row.state === 'docker-unavailable') return { ...row, health: 'docker-unavailable' };
183
+ if (row.state !== 'running') return { ...row, health: 'stopped' };
184
+ // A running container whose editor does not answer is BOOTING until
185
+ // its boot budget is spent, and broken after — never `starting`
186
+ // forever. An unparseable/absent `startedAt` keeps the old benefit of
187
+ // the doubt rather than inventing an age.
188
+ const startedAtMs = row.startedAt ? Date.parse(row.startedAt) : Number.NaN;
189
+ const unanswered: IsolatedWorktreeHealth =
190
+ Number.isFinite(startedAtMs) && Date.now() - startedAtMs > ISOLATED_EDITOR_BOOT_BUDGET_MS
191
+ ? 'unhealthy'
192
+ : 'starting';
193
+ try {
194
+ const response = await fetch(
195
+ `http://127.0.0.1:${row.editorPort}/__editor/compatibility`,
196
+ { signal: AbortSignal.timeout(1_000) },
197
+ );
198
+ return { ...row, health: response.ok ? 'healthy' : unanswered };
199
+ } catch {
200
+ return { ...row, health: unanswered };
201
+ }
202
+ }),
203
+ );
204
+ };
205
+
206
+ const currentWorktreeState = async () => {
207
+ const worktrees = await currentWorktrees();
208
+ const identity = currentSessionIdentity();
209
+ const directory = identity
210
+ ? await readRepositoryPresence(
211
+ liveSessions(),
212
+ identity.repositoryId,
213
+ identity.projectRelativePath,
214
+ )
215
+ : [];
216
+ const worktreesWithPresence = attachRepositoryPresence(worktrees, directory);
217
+ return {
218
+ worktrees: worktreesWithPresence,
219
+ branches: listRepositoryBranches(ctx.projectRoot, worktreesWithPresence),
220
+ isolatedWorktrees: await currentIsolatedWorktrees(),
221
+ };
222
+ };
223
+
224
+ const launchWorktreeEditor = async (
225
+ targetProject: string,
226
+ targetWorktreeRoot: string,
227
+ ): Promise<void> => {
228
+ const launch = worktreeEditorLaunchCommand({
229
+ targetProject,
230
+ targetWorktreeRoot,
231
+ inheritedCliEntry: process.env['VGAI_CLI_ENTRY'],
232
+ });
233
+ const env = { ...process.env };
234
+ delete env['VGAI_PROJECT'];
235
+ delete env['VGAI_EDITOR_PORT'];
236
+ delete env['VGAI_NO_OPEN'];
237
+ delete env['VGAI_RESTART_ON_SOURCE_CHANGE'];
238
+ env['VGAI_DETACH_AFTER_READY'] = '1';
239
+ await new Promise<void>((resolveLaunch, rejectLaunch) => {
240
+ execFile(
241
+ launch.command,
242
+ launch.args,
243
+ {
244
+ cwd: launch.cwd,
245
+ env,
246
+ maxBuffer: 4 * 1024 * 1024,
247
+ },
248
+ (error, _stdout, stderr) => {
249
+ if (error) {
250
+ rejectLaunch(new Error(stderr.trim() || error.message));
251
+ return;
252
+ }
253
+ resolveLaunch();
254
+ },
255
+ );
256
+ });
257
+ };
258
+
259
+ const focusWorktree = async (target: WorktreeView): Promise<{ url: string; status: string }> => {
260
+ if (!target.project) {
261
+ throw new Error('This worktree does not contain the project at the same repository path.');
262
+ }
263
+ let session = liveSessions().find(
264
+ (candidate) =>
265
+ candidate.worktreeId === target.worktreeId && candidate.project === target.project,
266
+ );
267
+ if (!session) {
268
+ await launchWorktreeEditor(target.project, target.root);
269
+ session = liveSessions().find(
270
+ (candidate) =>
271
+ candidate.worktreeId === target.worktreeId && candidate.project === target.project,
272
+ );
273
+ }
274
+ if (!session) throw new Error('The worktree editor did not register after launch.');
275
+ const response = await fetch(`http://127.0.0.1:${session.port}/__editor/tab/ensure`, {
276
+ method: 'POST',
277
+ headers: {
278
+ 'Content-Type': 'application/json',
279
+ Origin: `http://127.0.0.1:${session.port}`,
280
+ ...(session.controlSecret ? { 'x-vgai-editor-control': session.controlSecret } : {}),
281
+ },
282
+ body: JSON.stringify({ open: true }),
283
+ });
284
+ const result = (await response.json().catch(() => null)) as { status?: string } | null;
285
+ if (!response.ok) throw new Error(`Could not focus the editor on port ${session.port}.`);
286
+ return {
287
+ url: `http://127.0.0.1:${session.port}/`,
288
+ status: result?.status ?? 'focused',
289
+ };
290
+ };
291
+
292
+ const createAndOpenWorktree = async (value: unknown) => {
293
+ const body = value as { branch?: unknown; from?: unknown };
294
+ if (typeof body.branch !== 'string' || !body.branch.trim()) {
295
+ throw new Error('Enter a branch name.');
296
+ }
297
+ if (body.from !== undefined && typeof body.from !== 'string') {
298
+ throw new Error('The starting revision must be a string.');
299
+ }
300
+ const from = typeof body.from === 'string' ? body.from.trim() : '';
301
+ const created = createRepositoryWorktree(ctx.projectRoot, {
302
+ branch: body.branch.trim(),
303
+ ...(from ? { from } : {}),
304
+ });
305
+ if (!created.project) {
306
+ throw new Error(`Created ${created.root}, but it has no matching project to open.`);
307
+ }
308
+ await prepareRepositoryWorktree(ctx.projectRoot, created.root, created.project);
309
+ const target = (await currentWorktrees()).find((row) => row.branch === created.branch);
310
+ if (!target) throw new Error('The created worktree could not be rediscovered.');
311
+ return { created, worktreeId: target.worktreeId, ...(await focusWorktree(target)) };
312
+ };
313
+
314
+ const remoteHarnessIntent = async (
315
+ session: { port: number; controlSecret?: string | null },
316
+ intent: Record<string, unknown>,
317
+ ): Promise<Record<string, unknown>> => {
318
+ const response = await fetch(`http://127.0.0.1:${session.port}/__editor/harness-chat/intent`, {
319
+ method: 'POST',
320
+ headers: {
321
+ 'Content-Type': 'application/json',
322
+ ...(session.controlSecret ? { 'x-vgai-editor-control': session.controlSecret } : {}),
323
+ },
324
+ body: JSON.stringify(intent),
325
+ });
326
+ const payload = (await response.json().catch(() => null)) as Record<string, unknown> | null;
327
+ if (!response.ok) {
328
+ throw new Error(
329
+ typeof payload?.['error'] === 'string'
330
+ ? payload['error']
331
+ : `The delegated editor rejected the messenger intent (${response.status}).`,
332
+ );
333
+ }
334
+ return payload ?? {};
335
+ };
336
+
337
+ router.get('/__editor/worktrees', async (req: Request, res: Response) => {
338
+ if (!requireLocalOwner(req, res)) return;
339
+ try {
340
+ res.json(await currentWorktreeState());
341
+ } catch (error) {
342
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
343
+ }
344
+ });
345
+
346
+ // Repository-wide presence is safe for shared participants even though the
347
+ // worktree manager is not. This projection deliberately contains no local
348
+ // paths, ports, PIDs, control credentials, dirty state, or Git remotes.
349
+ router.get('/__editor/repository-presence', async (_req: Request, res: Response) => {
350
+ try {
351
+ if (ctx.projectRoot === engineRoot) {
352
+ res.json({ currentWorktreeId: null, sessions: [] });
353
+ return;
354
+ }
355
+ const identity = currentSessionIdentity();
356
+ if (!identity) {
357
+ res.json({ currentWorktreeId: null, sessions: [] });
358
+ return;
359
+ }
360
+ const directory = await readRepositoryPresence(
361
+ liveSessions(),
362
+ identity.repositoryId,
363
+ identity.projectRelativePath,
364
+ );
365
+ res.json({
366
+ currentWorktreeId: identity.worktreeId,
367
+ sessions: directory.map((entry) => ({
368
+ sessionId: entry.sessionId,
369
+ worktreeId: entry.worktreeId,
370
+ branch: entry.branch,
371
+ updatedAt: entry.updatedAt,
372
+ participants: entry.participants.map((participant) => ({
373
+ participantId: participant.participantId,
374
+ displayName: participant.displayName,
375
+ kind: participant.kind,
376
+ color: participant.color,
377
+ status: participant.status,
378
+ lastSeenAt: participant.lastSeenAt,
379
+ agent: participant.agent ? { harness: participant.agent.harness } : null,
380
+ changeCount: participant.changeCount,
381
+ })),
382
+ })),
383
+ });
384
+ } catch (error) {
385
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
386
+ }
387
+ });
388
+
389
+ router.post('/__editor/worktrees/open', async (req: Request, res: Response) => {
390
+ if (!requireLocalOwner(req, res)) return;
391
+ try {
392
+ const worktreeId = (req.body as { worktreeId?: unknown })?.worktreeId;
393
+ if (typeof worktreeId !== 'string') throw new Error('Expected a worktree identity.');
394
+ const target = (await currentWorktrees()).find((row) => row.worktreeId === worktreeId);
395
+ if (!target) throw new Error('That worktree no longer exists.');
396
+ res.json(await focusWorktree(target));
397
+ } catch (error) {
398
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
399
+ }
400
+ });
401
+
402
+ router.post('/__editor/worktrees/create', async (req: Request, res: Response) => {
403
+ if (!requireLocalOwner(req, res)) return;
404
+ try {
405
+ res.json(await createAndOpenWorktree(req.body));
406
+ } catch (error) {
407
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
408
+ }
409
+ });
410
+
411
+ router.post('/__editor/worktrees/delegate', async (req: Request, res: Response) => {
412
+ if (!requireLocalOwner(req, res)) return;
413
+ const body = (req.body ?? {}) as Record<string, unknown>;
414
+ if (
415
+ typeof body['task'] !== 'string' ||
416
+ !body['task'].trim() ||
417
+ body['task'].length > 20_000 ||
418
+ typeof body['harness'] !== 'string' ||
419
+ !body['harness'].trim() ||
420
+ !['worktree', 'current', 'container'].includes(String(body['isolation']))
421
+ ) {
422
+ res.status(400).json({ error: 'Expected task, harness, and isolation.' });
423
+ return;
424
+ }
425
+ try {
426
+ const task = body['task'].trim();
427
+ const harness = body['harness'].trim();
428
+ const isolation = body['isolation'];
429
+ if (isolation === 'current') {
430
+ const snapshot = await harnessChat.actIntent({
431
+ action: 'new',
432
+ harness,
433
+ text: task,
434
+ context: [
435
+ {
436
+ id: `delegation:${randomUUID()}`,
437
+ label: 'Delegated in the current worktree',
438
+ detail: ctx.projectRoot,
439
+ },
440
+ ],
441
+ });
442
+ res.json({ isolation, snapshot });
443
+ return;
444
+ }
445
+ if (typeof body['branch'] !== 'string' || !body['branch'].trim()) {
446
+ throw new Error('A delegated worktree needs a branch name.');
447
+ }
448
+ if (isolation === 'container') {
449
+ if (harness !== 'claude' && harness !== 'codex') {
450
+ throw new Error('Isolated delegation supports the Claude and Codex harnesses.');
451
+ }
452
+ const branch = body['branch'].trim();
453
+ const from =
454
+ typeof body['from'] === 'string' && body['from'].trim() ? body['from'] : 'HEAD';
455
+ await runIsolatedCli(['create', branch, '--from', from]);
456
+ const isolated = (await currentIsolatedWorktrees()).find((row) => row.branch === branch);
457
+ if (!isolated) throw new Error('The isolated worktree started but was not registered.');
458
+ res.json({
459
+ isolation,
460
+ isolated,
461
+ task,
462
+ requiresAuthentication: true,
463
+ command: `vgai isolate agent ${isolated.id} ${harness}`,
464
+ message:
465
+ 'The credential-empty container is ready. Attach the harness and authenticate inside its temporary home, then send the task shown here.',
466
+ });
467
+ return;
468
+ }
469
+ const opened = await createAndOpenWorktree({
470
+ branch: body['branch'],
471
+ from: typeof body['from'] === 'string' ? body['from'] : 'HEAD',
472
+ });
473
+ const delegatedSession = liveSessions().find(
474
+ (session) => session.worktreeId === opened.worktreeId,
475
+ );
476
+ if (!delegatedSession) throw new Error('The delegated editor session is not registered.');
477
+ const snapshot = await remoteHarnessIntent(delegatedSession, {
478
+ action: 'new',
479
+ harness,
480
+ text: task,
481
+ context: [
482
+ {
483
+ id: `delegation:${randomUUID()}`,
484
+ label: `Delegated from ${currentSessionIdentity()?.branch ?? 'detached HEAD'}`,
485
+ detail: `Base ${typeof body['from'] === 'string' ? body['from'] : 'HEAD'}`,
486
+ },
487
+ ],
488
+ });
489
+ res.json({ isolation, ...opened, snapshot });
490
+ } catch (error) {
491
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
492
+ }
493
+ });
494
+
495
+ router.get('/__editor/worktrees/isolated/:id/logs', async (req: Request, res: Response) => {
496
+ if (!requireLocalOwner(req, res)) return;
497
+ try {
498
+ const parameter = req.params['id'];
499
+ const id = Array.isArray(parameter) ? parameter[0] : parameter;
500
+ const target = (await currentIsolatedWorktrees()).find((row) => row.id === id);
501
+ if (!target) throw new Error('That isolated worktree does not exist in this repository.');
502
+ res.json({ logs: await runIsolatedCli(['logs', target.id, '--lines', '120']) });
503
+ } catch (error) {
504
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
505
+ }
506
+ });
507
+
508
+ router.post('/__editor/worktrees/isolated/export', async (req: Request, res: Response) => {
509
+ if (!requireLocalOwner(req, res)) return;
510
+ try {
511
+ const id = (req.body as { id?: unknown })?.id;
512
+ if (typeof id !== 'string') throw new Error('Expected an isolated worktree identity.');
513
+ const target = (await currentIsolatedWorktrees()).find((row) => row.id === id);
514
+ if (!target) throw new Error('That isolated worktree does not exist in this repository.');
515
+ const output = await runIsolatedCli(['export', target.id]);
516
+ res.json({ ok: true, output, ...(await currentWorktreeState()) });
517
+ } catch (error) {
518
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
519
+ }
520
+ });
521
+
522
+ router.post('/__editor/worktrees/isolated/stop', async (req: Request, res: Response) => {
523
+ if (!requireLocalOwner(req, res)) return;
524
+ try {
525
+ const body = (req.body ?? {}) as Record<string, unknown>;
526
+ if (typeof body['id'] !== 'string' || typeof body['discard'] !== 'boolean') {
527
+ throw new Error('Expected an isolated worktree identity and explicit discard choice.');
528
+ }
529
+ const target = (await currentIsolatedWorktrees()).find((row) => row.id === body['id']);
530
+ if (!target) throw new Error('That isolated worktree does not exist in this repository.');
531
+ await runIsolatedCli(['stop', target.id, ...(body['discard'] ? ['--discard'] : [])]);
532
+ res.json({ ok: true, ...(await currentWorktreeState()) });
533
+ } catch (error) {
534
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
535
+ }
536
+ });
537
+
538
+ router.post('/__editor/worktrees/archive', async (req: Request, res: Response) => {
539
+ if (!requireLocalOwner(req, res)) return;
540
+ try {
541
+ const worktreeId = (req.body as { worktreeId?: unknown })?.worktreeId;
542
+ if (typeof worktreeId !== 'string') throw new Error('Expected a worktree identity.');
543
+ const rows = await currentWorktrees();
544
+ const target = rows.find((row) => row.worktreeId === worktreeId);
545
+ if (!target) throw new Error('That worktree no longer exists.');
546
+ archiveRepositoryWorktree(
547
+ ctx.projectRoot,
548
+ target.root,
549
+ publicWorktreeSessionRefs(liveSessions()),
550
+ );
551
+ res.json({ ok: true, ...(await currentWorktreeState()) });
552
+ } catch (error) {
553
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
554
+ }
555
+ });
556
+
557
+ router.post('/__editor/worktrees/stop', async (req: Request, res: Response) => {
558
+ if (!requireLocalOwner(req, res)) return;
559
+ try {
560
+ const body = (req.body ?? {}) as Record<string, unknown>;
561
+ if (typeof body['worktreeId'] !== 'string' || typeof body['sessionId'] !== 'string') {
562
+ throw new Error('Expected worktree and session identities.');
563
+ }
564
+ const session = liveSessions().find(
565
+ (candidate) =>
566
+ candidate.worktreeId === body['worktreeId'] && candidate.sessionId === body['sessionId'],
567
+ );
568
+ if (!session?.sessionId || !session.pid || session.pid === process.pid) {
569
+ throw new Error('That sibling editor session is not available to stop.');
570
+ }
571
+ const response = await fetch(`http://127.0.0.1:${session.port}/__editor/project`, {
572
+ cache: 'no-store',
573
+ signal: AbortSignal.timeout(1_000),
574
+ ...(session.controlSecret
575
+ ? { headers: { 'x-vgai-editor-control': session.controlSecret } }
576
+ : {}),
577
+ });
578
+ const identity = (await response.json().catch(() => null)) as {
579
+ session?: { sessionId?: unknown; worktreeId?: unknown; ephemeral?: unknown };
580
+ } | null;
581
+ if (
582
+ !response.ok ||
583
+ identity?.session?.ephemeral === true ||
584
+ identity?.session?.sessionId !== session.sessionId ||
585
+ identity.session.worktreeId !== session.worktreeId
586
+ ) {
587
+ throw new Error('The registered process no longer owns that editor session.');
588
+ }
589
+ process.kill(session.pid, 'SIGTERM');
590
+ res.json({ ok: true, sessionId: session.sessionId });
591
+ } catch (error) {
592
+ res.status(400).json({ error: error instanceof Error ? error.message : String(error) });
593
+ }
594
+ });
595
+ }