@volter/sdk 0.0.0-stage → 0.5.204

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 (523) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +20 -0
  3. package/README.md +38 -3
  4. package/package.json +510 -4
  5. package/src/account.ts +210 -0
  6. package/src/chrome.ts +88 -0
  7. package/src/client.ts +1646 -0
  8. package/src/commands.ts +66 -0
  9. package/src/contributions.ts +619 -0
  10. package/src/css-numeric-style.ts +97 -0
  11. package/src/document-probe.ts +282 -0
  12. package/src/editor-view.ts +225 -0
  13. package/src/extension.ts +40 -0
  14. package/src/generations.ts +178 -0
  15. package/src/host.ts +1157 -0
  16. package/src/http-transport.browser.ts +14 -0
  17. package/src/http-transport.node.ts +19 -0
  18. package/src/index.ts +131 -0
  19. package/src/kit/CapabilityCoverageSection.tsx +185 -0
  20. package/src/kit/account-client.ts +333 -0
  21. package/src/kit/action-registry.ts +317 -0
  22. package/src/kit/active-product.ts +76 -0
  23. package/src/kit/active-project.ts +155 -0
  24. package/src/kit/adapter-editor-config.ts +25 -0
  25. package/src/kit/adapter-module.ts +7 -0
  26. package/src/kit/adapter-observation.ts +49 -0
  27. package/src/kit/animation/animation-clock.ts +479 -0
  28. package/src/kit/animation/stage-transport.ts +385 -0
  29. package/src/kit/api/assets.ts +365 -0
  30. package/src/kit/api/project-open.ts +355 -0
  31. package/src/kit/api/project-source.ts +180 -0
  32. package/src/kit/api/project-state.ts +110 -0
  33. package/src/kit/api/relay.ts +270 -0
  34. package/src/kit/api/themes.ts +45 -0
  35. package/src/kit/api-asset-library-wire.ts +45 -0
  36. package/src/kit/api-base.ts +10 -0
  37. package/src/kit/api-build.ts +99 -0
  38. package/src/kit/api-git-wire.ts +56 -0
  39. package/src/kit/api-logs.ts +92 -0
  40. package/src/kit/api-project-identity.ts +74 -0
  41. package/src/kit/api-settings.ts +36 -0
  42. package/src/kit/api-worktrees.ts +205 -0
  43. package/src/kit/asset-capabilities.ts +344 -0
  44. package/src/kit/asset-compare-core.ts +171 -0
  45. package/src/kit/asset-editor-context.tsx +101 -0
  46. package/src/kit/asset-events.ts +96 -0
  47. package/src/kit/asset-inspector-actions.ts +87 -0
  48. package/src/kit/asset-selection-viewer-registry.ts +113 -0
  49. package/src/kit/asset-selection.ts +146 -0
  50. package/src/kit/asset-thumbnails.ts +25 -0
  51. package/src/kit/asset-viewers.ts +115 -0
  52. package/src/kit/asset-workflow/asset-import-jobs.ts +106 -0
  53. package/src/kit/asset-workflow/asset-ledger-backend.ts +126 -0
  54. package/src/kit/asset-workflow/asset-ledger.ts +156 -0
  55. package/src/kit/asset-workflow/asset-materialization-report.ts +140 -0
  56. package/src/kit/asset-workflow/asset-pack-manifest.ts +320 -0
  57. package/src/kit/asset-workflow/asset-types.ts +142 -0
  58. package/src/kit/asset-workflow/audio-preview-player.ts +193 -0
  59. package/src/kit/asset-workflow/audio-waveform.ts +22 -0
  60. package/src/kit/asset-workflow/cloud-asset-client.ts +263 -0
  61. package/src/kit/asset-workflow/hosted-asset-materialization.ts +236 -0
  62. package/src/kit/asset-workflow/image-view-scale.ts +31 -0
  63. package/src/kit/asset-workflow/import-contract.ts +124 -0
  64. package/src/kit/asset-workflow/ledger-write-lock.ts +244 -0
  65. package/src/kit/asset-workflow/pixi-spritesheet.ts +197 -0
  66. package/src/kit/asset-workflow/preview-resource-lifetime.ts +44 -0
  67. package/src/kit/asset-workflow/project-asset-commands.ts +20 -0
  68. package/src/kit/asset-workflow/project-content.ts +288 -0
  69. package/src/kit/asset-workflow/project-source-index.ts +545 -0
  70. package/src/kit/asset-workflow/thumbnail-system.ts +256 -0
  71. package/src/kit/authoring/active-adapter.ts +200 -0
  72. package/src/kit/authoring/active-systems.ts +422 -0
  73. package/src/kit/authoring/adapter-key.ts +18 -0
  74. package/src/kit/authoring/authoring-asset-url.ts +27 -0
  75. package/src/kit/authoring/bootstrap-state.ts +49 -0
  76. package/src/kit/authoring/boundary-authoring-adapter.ts +189 -0
  77. package/src/kit/authoring/canvas-scene-guides.ts +84 -0
  78. package/src/kit/authoring/composite-authoring-adapter.ts +2109 -0
  79. package/src/kit/authoring/consumer-actions.ts +531 -0
  80. package/src/kit/authoring/design-time-layers.ts +852 -0
  81. package/src/kit/authoring/design-time-mount-registry.ts +244 -0
  82. package/src/kit/authoring/edit-mode-authoring.ts +637 -0
  83. package/src/kit/authoring/empty-project-authoring.ts +22 -0
  84. package/src/kit/authoring/instance-source-menu.ts +135 -0
  85. package/src/kit/authoring/layered-pick.ts +185 -0
  86. package/src/kit/authoring/mounted-root-subjects.ts +146 -0
  87. package/src/kit/authoring/no-authoring-adapter.ts +59 -0
  88. package/src/kit/authoring/object3d-document-persistence.ts +122 -0
  89. package/src/kit/authoring/panel-authoring.ts +121 -0
  90. package/src/kit/authoring/project-authoring-session.ts +105 -0
  91. package/src/kit/authoring/provenance.ts +99 -0
  92. package/src/kit/authoring/react-canvas-navigation.ts +259 -0
  93. package/src/kit/authoring/react-design-canvas-style.ts +20 -0
  94. package/src/kit/authoring/react-story-board.ts +917 -0
  95. package/src/kit/authoring/selection-scope.ts +195 -0
  96. package/src/kit/authoring/shell-document-ops.ts +169 -0
  97. package/src/kit/authoring/story-board-chrome-fit.ts +107 -0
  98. package/src/kit/authoring/story-board-presentation.ts +111 -0
  99. package/src/kit/authoring/three-root.ts +67 -0
  100. package/src/kit/authoring/viewport-tool-context.ts +73 -0
  101. package/src/kit/authoring/viewport-tool-owner.ts +38 -0
  102. package/src/kit/authoring/world-session-state.ts +101 -0
  103. package/src/kit/authoring-seam-evidence.ts +300 -0
  104. package/src/kit/availability-tick.ts +66 -0
  105. package/src/kit/bitmap-label.ts +120 -0
  106. package/src/kit/boot-routing.ts +392 -0
  107. package/src/kit/breakpoint-state.ts +43 -0
  108. package/src/kit/build-identity.ts +16 -0
  109. package/src/kit/bytes-codec.ts +62 -0
  110. package/src/kit/cancellation-reason.ts +58 -0
  111. package/src/kit/canvas-frames.ts +88 -0
  112. package/src/kit/capture-camera-pose.ts +77 -0
  113. package/src/kit/capture-size.ts +88 -0
  114. package/src/kit/chrome-registry.ts +159 -0
  115. package/src/kit/chrome-slot-registry.ts +91 -0
  116. package/src/kit/collaboration-client.ts +264 -0
  117. package/src/kit/collaboration-presence.ts +41 -0
  118. package/src/kit/command-dispatch.ts +19 -0
  119. package/src/kit/command-listener.ts +2182 -0
  120. package/src/kit/command-registry.ts +71 -0
  121. package/src/kit/component-board-registry.ts +205 -0
  122. package/src/kit/component-states-registry.ts +199 -0
  123. package/src/kit/components/AlignToolbar.tsx +204 -0
  124. package/src/kit/components/ApplicationMenus.tsx +372 -0
  125. package/src/kit/components/AssetEditorShell.tsx +216 -0
  126. package/src/kit/components/AssetInspectorToolSection.tsx +124 -0
  127. package/src/kit/components/BoardRulers.tsx +354 -0
  128. package/src/kit/components/CanvasAddNodeDialogs.tsx +529 -0
  129. package/src/kit/components/CanvasSceneViewport.tsx +1195 -0
  130. package/src/kit/components/ChromeSlot.tsx +20 -0
  131. package/src/kit/components/CodeView.tsx +470 -0
  132. package/src/kit/components/CompactInspectorShell.tsx +39 -0
  133. package/src/kit/components/ConsolePanel.tsx +273 -0
  134. package/src/kit/components/GameplaySessionTimeline.tsx +295 -0
  135. package/src/kit/components/InspectionProjection.tsx +932 -0
  136. package/src/kit/components/Inspector.tsx +270 -0
  137. package/src/kit/components/InspectorCanvasPreview.tsx +35 -0
  138. package/src/kit/components/InspectorFieldsSection.tsx +290 -0
  139. package/src/kit/components/InspectorStoriesSection.tsx +92 -0
  140. package/src/kit/components/InspectorToolSection.tsx +96 -0
  141. package/src/kit/components/InspectorTransformSection.tsx +245 -0
  142. package/src/kit/components/LightExplorerPanel.tsx +433 -0
  143. package/src/kit/components/MediaProperties.tsx +145 -0
  144. package/src/kit/components/ProjectHeader.tsx +328 -0
  145. package/src/kit/components/ReactCanvasControls.tsx +358 -0
  146. package/src/kit/components/RootSelectionOverlay.tsx +3688 -0
  147. package/src/kit/components/RootTextEditor.tsx +79 -0
  148. package/src/kit/components/SaveStatus.tsx +70 -0
  149. package/src/kit/components/SurfaceCrashBoundary.tsx +105 -0
  150. package/src/kit/components/SurfaceStateOverlay.tsx +24 -0
  151. package/src/kit/components/ToolContributionSurfaces.tsx +49 -0
  152. package/src/kit/components/ToolHost.tsx +380 -0
  153. package/src/kit/components/Toolbar.tsx +811 -0
  154. package/src/kit/components/TransientHint.tsx +44 -0
  155. package/src/kit/components/VersionControlSection.tsx +470 -0
  156. package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
  157. package/src/kit/components/VolterLogo.tsx +18 -0
  158. package/src/kit/components/WorktreeSwitcher.tsx +712 -0
  159. package/src/kit/components/account-documents.tsx +1162 -0
  160. package/src/kit/components/asset-documents.tsx +794 -0
  161. package/src/kit/components/asset-editor-persistence.ts +216 -0
  162. package/src/kit/components/asset-selection-section.tsx +545 -0
  163. package/src/kit/components/asset-thumbnails.tsx +307 -0
  164. package/src/kit/components/asset-viewers/AudioViewer.tsx +201 -0
  165. package/src/kit/components/asset-viewers/GenericJsonViewer.tsx +102 -0
  166. package/src/kit/components/asset-viewers/ImageViewer.tsx +300 -0
  167. package/src/kit/components/asset-viewers/JsonAssetDocument.tsx +98 -0
  168. package/src/kit/components/asset-viewers/OnlineAssetDetail.tsx +426 -0
  169. package/src/kit/components/asset-viewers/SourceAssetViewer.tsx +356 -0
  170. package/src/kit/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
  171. package/src/kit/components/asset-viewers/VideoViewer.tsx +101 -0
  172. package/src/kit/components/asset-viewers/shader-source.ts +144 -0
  173. package/src/kit/components/board-guides.ts +150 -0
  174. package/src/kit/components/canvas-scene-hotkeys.ts +37 -0
  175. package/src/kit/components/canvas-temporary-pivot.ts +34 -0
  176. package/src/kit/components/core-utilities.tsx +94 -0
  177. package/src/kit/components/inspector-preview-section.tsx +223 -0
  178. package/src/kit/components/inspector-revert-label.ts +20 -0
  179. package/src/kit/components/inspector-selection.ts +42 -0
  180. package/src/kit/components/inspector-stories-gating.ts +171 -0
  181. package/src/kit/components/inspector-transform-subject.ts +11 -0
  182. package/src/kit/components/inspector-transform.ts +88 -0
  183. package/src/kit/components/kind-documents.tsx +544 -0
  184. package/src/kit/components/primitives/DraftColorInput.tsx +74 -0
  185. package/src/kit/components/project-tool-documents.tsx +402 -0
  186. package/src/kit/components/scene-documents.tsx +221 -0
  187. package/src/kit/components/status-contributions.tsx +407 -0
  188. package/src/kit/components/tool-documents.tsx +302 -0
  189. package/src/kit/components/tool-schema-form.tsx +262 -0
  190. package/src/kit/components/use-after-paint.ts +41 -0
  191. package/src/kit/components/use-project-image-assets.ts +86 -0
  192. package/src/kit/components/workspace-history.ts +32 -0
  193. package/src/kit/components/world-documents.tsx +570 -0
  194. package/src/kit/components/world-overlay-gestures.ts +1939 -0
  195. package/src/kit/composite-screenshot.ts +2238 -0
  196. package/src/kit/content-entry-source-registry.ts +184 -0
  197. package/src/kit/contribution-surfaces.ts +48 -0
  198. package/src/kit/coverage/canvas-reveal.ts +192 -0
  199. package/src/kit/coverage/design-time-surfaces.ts +101 -0
  200. package/src/kit/coverage/ontology-invariants.ts +466 -0
  201. package/src/kit/coverage/session-vitals.ts +503 -0
  202. package/src/kit/crash-null-boundary.ts +36 -0
  203. package/src/kit/creation-site-edit.ts +1491 -0
  204. package/src/kit/creation-site-registry.ts +160 -0
  205. package/src/kit/delegate-harness-registry.ts +134 -0
  206. package/src/kit/document-areas.ts +70 -0
  207. package/src/kit/document-context-registry.ts +193 -0
  208. package/src/kit/document-open-registry.ts +200 -0
  209. package/src/kit/document-play-extension.ts +221 -0
  210. package/src/kit/document-preview-source.ts +20 -0
  211. package/src/kit/document-renderer-session.ts +138 -0
  212. package/src/kit/document-stage-sessions.ts +26 -0
  213. package/src/kit/document-viewports.ts +120 -0
  214. package/src/kit/editor-api.ts +46 -0
  215. package/src/kit/editor-chrome-capture.ts +136 -0
  216. package/src/kit/editor-commands.ts +176 -0
  217. package/src/kit/editor-console.ts +580 -0
  218. package/src/kit/editor-current-view.ts +56 -0
  219. package/src/kit/editor-document-probe.ts +1168 -0
  220. package/src/kit/editor-git-client.ts +115 -0
  221. package/src/kit/editor-hotkeys.ts +728 -0
  222. package/src/kit/editor-lease-view.ts +39 -0
  223. package/src/kit/editor-lease.ts +415 -0
  224. package/src/kit/editor-mode.ts +19 -0
  225. package/src/kit/editor-notifications.ts +140 -0
  226. package/src/kit/editor-presence.ts +563 -0
  227. package/src/kit/editor-presentation-activity.ts +58 -0
  228. package/src/kit/editor-presentation-notice.ts +42 -0
  229. package/src/kit/editor-runtime.tsx +147 -0
  230. package/src/kit/editor-server-response.ts +86 -0
  231. package/src/kit/editor-session-attribution.ts +85 -0
  232. package/src/kit/editor-session-mode.ts +54 -0
  233. package/src/kit/editor-state-facets.ts +74 -0
  234. package/src/kit/editor-view-presentation.ts +777 -0
  235. package/src/kit/environment-images.ts +58 -0
  236. package/src/kit/eyedropper-session.ts +60 -0
  237. package/src/kit/files/file-provider.ts +62 -0
  238. package/src/kit/files/project-files.ts +270 -0
  239. package/src/kit/finders/index.ts +137 -0
  240. package/src/kit/finders/scenes-from-entrypoint-selection.ts +387 -0
  241. package/src/kit/frame/frame-parts.ts +30 -0
  242. package/src/kit/framed-document-capture.ts +34 -0
  243. package/src/kit/game-globals-prelude.ts +143 -0
  244. package/src/kit/game-surface-defaults.ts +33 -0
  245. package/src/kit/gameplay-dom-recording.ts +318 -0
  246. package/src/kit/gameplay-export-state.ts +14 -0
  247. package/src/kit/gameplay-replay.ts +417 -0
  248. package/src/kit/gameplay-session-time.ts +9 -0
  249. package/src/kit/gameplay-sessions.ts +204 -0
  250. package/src/kit/hierarchy-component-marks.ts +298 -0
  251. package/src/kit/hierarchy-internals.ts +197 -0
  252. package/src/kit/hierarchy-kind-icon.ts +217 -0
  253. package/src/kit/hierarchy-menu-registry.ts +67 -0
  254. package/src/kit/hierarchy-node-rows.ts +307 -0
  255. package/src/kit/hierarchy-panel-view.ts +280 -0
  256. package/src/kit/hierarchy-projection.ts +76 -0
  257. package/src/kit/hierarchy-row-media.ts +45 -0
  258. package/src/kit/hierarchy-row-model.ts +308 -0
  259. package/src/kit/hierarchy-rows.ts +11 -0
  260. package/src/kit/hierarchy-walk.ts +86 -0
  261. package/src/kit/history/editor-session.ts +25 -0
  262. package/src/kit/history/history-commands.ts +147 -0
  263. package/src/kit/history/history-delegate.ts +187 -0
  264. package/src/kit/history/history-limit-notices.ts +43 -0
  265. package/src/kit/history/history-service.ts +1189 -0
  266. package/src/kit/history/persistence-coordinator.ts +35 -0
  267. package/src/kit/history/project-file-history.ts +386 -0
  268. package/src/kit/history/project-root-history-backends.ts +139 -0
  269. package/src/kit/history/resource-registry.ts +209 -0
  270. package/src/kit/history/snapshot-store.ts +103 -0
  271. package/src/kit/history/source-history-backend.ts +546 -0
  272. package/src/kit/history-types.ts +124 -0
  273. package/src/kit/hmr-registration-group.ts +67 -0
  274. package/src/kit/hmr-stable-react-context.ts +23 -0
  275. package/src/kit/hotkeys.ts +190 -0
  276. package/src/kit/inference-diagnostics.ts +69 -0
  277. package/src/kit/initial-project.ts +80 -0
  278. package/src/kit/inspection/active-subject.ts +571 -0
  279. package/src/kit/inspection/active-surface.ts +142 -0
  280. package/src/kit/inspection/compose-subject.ts +1055 -0
  281. package/src/kit/inspection/compose.ts +7 -0
  282. package/src/kit/inspection/display.ts +171 -0
  283. package/src/kit/inspection/document-subject.ts +109 -0
  284. package/src/kit/inspection/game-subject.ts +85 -0
  285. package/src/kit/inspection/null-subject.ts +119 -0
  286. package/src/kit/inspection/serialize.ts +357 -0
  287. package/src/kit/inspection/use-active-inspection.ts +180 -0
  288. package/src/kit/inspection-model.ts +542 -0
  289. package/src/kit/inspection-node-media.ts +58 -0
  290. package/src/kit/inspector-presentation.ts +203 -0
  291. package/src/kit/inspector-property-grouping.ts +64 -0
  292. package/src/kit/inspector-section-registry.ts +221 -0
  293. package/src/kit/instance-source-actions.ts +163 -0
  294. package/src/kit/js-heap.ts +71 -0
  295. package/src/kit/key-actions.ts +91 -0
  296. package/src/kit/keymap-presets.ts +428 -0
  297. package/src/kit/layout-policy.ts +31 -0
  298. package/src/kit/light-explorer-model.ts +134 -0
  299. package/src/kit/live-canvas-frame.ts +55 -0
  300. package/src/kit/live-document.ts +296 -0
  301. package/src/kit/live-gesture-lock.ts +50 -0
  302. package/src/kit/live-seam-evidence.ts +11 -0
  303. package/src/kit/live-session-registry.ts +220 -0
  304. package/src/kit/live-transition.ts +391 -0
  305. package/src/kit/manifest-project.ts +107 -0
  306. package/src/kit/module-fetch-diagnosis.ts +192 -0
  307. package/src/kit/mount-failure-report.ts +154 -0
  308. package/src/kit/native-selection-style.ts +497 -0
  309. package/src/kit/object3d-document-write-policy.ts +137 -0
  310. package/src/kit/packaged-runtime.ts +108 -0
  311. package/src/kit/palettes/maya.palette.json +57 -0
  312. package/src/kit/palettes/substance.palette.json +57 -0
  313. package/src/kit/performance-profiler.ts +367 -0
  314. package/src/kit/performance-sources.ts +69 -0
  315. package/src/kit/photograph-notice.ts +141 -0
  316. package/src/kit/play-boot-phase.ts +166 -0
  317. package/src/kit/play-camera-flight.ts +35 -0
  318. package/src/kit/png-encode.worker.ts +26 -0
  319. package/src/kit/presentation-surface.ts +248 -0
  320. package/src/kit/product-command.ts +90 -0
  321. package/src/kit/project-adapter.ts +1140 -0
  322. package/src/kit/project-asset-refresh.ts +23 -0
  323. package/src/kit/project-asset-roots.ts +68 -0
  324. package/src/kit/project-local-state.ts +151 -0
  325. package/src/kit/project-manager.ts +243 -0
  326. package/src/kit/project-module-changes.ts +201 -0
  327. package/src/kit/project-module-split.ts +270 -0
  328. package/src/kit/project-play-layers.ts +25 -0
  329. package/src/kit/project-provenance.ts +115 -0
  330. package/src/kit/project-ready.ts +42 -0
  331. package/src/kit/project-shape.ts +68 -0
  332. package/src/kit/project-tools.ts +107 -0
  333. package/src/kit/projection-types.ts +44 -0
  334. package/src/kit/readiness.ts +113 -0
  335. package/src/kit/renderer-resource-counts.ts +27 -0
  336. package/src/kit/reported-play-state.ts +90 -0
  337. package/src/kit/resolve-contributed-command.ts +14 -0
  338. package/src/kit/resolve-relative-specifier.ts +33 -0
  339. package/src/kit/retained-document-states.ts +91 -0
  340. package/src/kit/scene-document-plan.ts +320 -0
  341. package/src/kit/scene-live-open.ts +210 -0
  342. package/src/kit/scoped-game-css.ts +152 -0
  343. package/src/kit/served-url.ts +5 -0
  344. package/src/kit/session-close.ts +17 -0
  345. package/src/kit/session-tombstone.ts +127 -0
  346. package/src/kit/settings/settings-provider.ts +82 -0
  347. package/src/kit/settings-store.ts +348 -0
  348. package/src/kit/shell-document-state.ts +27 -0
  349. package/src/kit/shell-store-door.ts +45 -0
  350. package/src/kit/shell-store.ts +722 -0
  351. package/src/kit/source-conflict.ts +122 -0
  352. package/src/kit/stage-context.ts +377 -0
  353. package/src/kit/stage-invalidation.ts +25 -0
  354. package/src/kit/stage-store-registry.ts +69 -0
  355. package/src/kit/startup-failure.ts +80 -0
  356. package/src/kit/state-report-deferral.ts +73 -0
  357. package/src/kit/storage/host-files-storage.ts +97 -0
  358. package/src/kit/storage/http-storage.ts +174 -0
  359. package/src/kit/storage/index.ts +75 -0
  360. package/src/kit/storage/mem-storage.ts +158 -0
  361. package/src/kit/storage/path-lock.ts +44 -0
  362. package/src/kit/storage/paths.ts +26 -0
  363. package/src/kit/storage-types.ts +127 -0
  364. package/src/kit/stories/StoryPreviewMount.tsx +306 -0
  365. package/src/kit/stories/compose-project-stories.ts +255 -0
  366. package/src/kit/stories/prefabs-finder.ts +54 -0
  367. package/src/kit/stories/prefabs-from-stories.ts +182 -0
  368. package/src/kit/stories/project-story-regions.ts +24 -0
  369. package/src/kit/stories/story-capture.ts +579 -0
  370. package/src/kit/stories/story-declared-medium.ts +126 -0
  371. package/src/kit/stories/story-discovery.ts +176 -0
  372. package/src/kit/stories/story-dom-runtime.ts +78 -0
  373. package/src/kit/stories/story-grouping.ts +111 -0
  374. package/src/kit/stories/story-mount-turn.ts +27 -0
  375. package/src/kit/stories/story-presentation.ts +215 -0
  376. package/src/kit/stories/story-preview-component.ts +7 -0
  377. package/src/kit/stories/story-registry.ts +530 -0
  378. package/src/kit/stories-scope.ts +35 -0
  379. package/src/kit/story-document-openers.ts +36 -0
  380. package/src/kit/story-thumbnails.ts +47 -0
  381. package/src/kit/surface-keyboard.ts +101 -0
  382. package/src/kit/surface-state.ts +135 -0
  383. package/src/kit/system-seam-evidence.ts +72 -0
  384. package/src/kit/tab-census.ts +202 -0
  385. package/src/kit/tab-lifecycle-client.ts +227 -0
  386. package/src/kit/theme-library.ts +897 -0
  387. package/src/kit/theme-preference.ts +429 -0
  388. package/src/kit/three-viewport-presentation.ts +23 -0
  389. package/src/kit/tool-contribution-play.ts +74 -0
  390. package/src/kit/tool-loader.ts +1918 -0
  391. package/src/kit/transform-mode-request.ts +66 -0
  392. package/src/kit/transient-hint.ts +78 -0
  393. package/src/kit/transport-strip.tsx +174 -0
  394. package/src/kit/ui-source/adapter-region-includes.ts +238 -0
  395. package/src/kit/ui-source/file-region-resolver.ts +302 -0
  396. package/src/kit/ui-source/inspect.ts +775 -0
  397. package/src/kit/ui-source/source-write-backend.ts +605 -0
  398. package/src/kit/ui-source/tier-source-write-backend.ts +279 -0
  399. package/src/kit/user-local-state.ts +105 -0
  400. package/src/kit/viewport-activation-timings.ts +840 -0
  401. package/src/kit/viewport-editor-controls.ts +22 -0
  402. package/src/kit/viewport-presentation.ts +668 -0
  403. package/src/kit/viewport-surface-status.tsx +55 -0
  404. package/src/kit/wait-until.ts +37 -0
  405. package/src/kit/worker-call-metrics.ts +166 -0
  406. package/src/kit/workspace-areas.ts +191 -0
  407. package/src/kit/workspace-aux-commands.ts +11 -0
  408. package/src/kit/workspace-available-documents.ts +142 -0
  409. package/src/kit/workspace-core-utilities.ts +31 -0
  410. package/src/kit/workspace-document-ids.ts +59 -0
  411. package/src/kit/workspace-document-registry.ts +624 -0
  412. package/src/kit/workspace-document-restore.ts +146 -0
  413. package/src/kit/workspace-host-commands.ts +141 -0
  414. package/src/kit/workspace-persistence-gate.ts +40 -0
  415. package/src/kit/workspace-play-utilities.ts +44 -0
  416. package/src/kit/workspace-presets.ts +446 -0
  417. package/src/kit/workspace-regions.ts +276 -0
  418. package/src/kit/workspace-static-panels.ts +73 -0
  419. package/src/kit/workspace-status-registry.ts +121 -0
  420. package/src/kit/workspace-storage.ts +35 -0
  421. package/src/kit/workspace-style.ts +226 -0
  422. package/src/kit/workspace-utility-commands.ts +74 -0
  423. package/src/kit/workspace-utility-registry.ts +263 -0
  424. package/src/kit/world-adoption-event.ts +23 -0
  425. package/src/kit/world-adoption.ts +115 -0
  426. package/src/kit/world-canvas-viewport-state.ts +35 -0
  427. package/src/kit/world-document-routing.ts +104 -0
  428. package/src/kit/world-pan-state.ts +198 -0
  429. package/src/kit/write-pipe.ts +173 -0
  430. package/src/layout-arrangements.ts +5 -0
  431. package/src/layouts.tsx +108 -0
  432. package/src/looks.ts +16 -0
  433. package/src/project/output-roots.ts +73 -0
  434. package/src/project/tab-census.ts +155 -0
  435. package/src/project-tool-catalog.ts +104 -0
  436. package/src/selection.tsx +107 -0
  437. package/src/services.ts +18 -0
  438. package/src/session/build-report.ts +22 -0
  439. package/src/session/collaboration-types.ts +262 -0
  440. package/src/session/command-table.ts +327 -0
  441. package/src/session/discovery.ts +100 -0
  442. package/src/session/editor-brand.ts +48 -0
  443. package/src/session/editor-compatibility.ts +329 -0
  444. package/src/session/editor-control-lifecycle.ts +68 -0
  445. package/src/session/editor-control-protocol.ts +5 -0
  446. package/src/session/entrypoint-selection-readers.ts +66 -0
  447. package/src/session/entrypoint-selection-source.ts +120 -0
  448. package/src/session/game-css-scope.ts +30 -0
  449. package/src/session/hosted-attachment.ts +225 -0
  450. package/src/session/limited-view.ts +82 -0
  451. package/src/session/product-create.ts +24 -0
  452. package/src/session/product-locator.ts +478 -0
  453. package/src/session/project-module-url.ts +242 -0
  454. package/src/session/project-serving.ts +164 -0
  455. package/src/session/project-upgrade.ts +669 -0
  456. package/src/session/registry-format.ts +210 -0
  457. package/src/session/relative-path-guard.ts +56 -0
  458. package/src/session/scoped-game-css.ts +461 -0
  459. package/src/session/source-glob.ts +15 -0
  460. package/src/session/tool-contribution-convention.ts +123 -0
  461. package/src/session/workbench-locator.ts +712 -0
  462. package/src/session.ts +41 -0
  463. package/src/share.ts +160 -0
  464. package/src/source-analysis.ts +28 -0
  465. package/src/source-authoring.ts +439 -0
  466. package/src/tools/errors.ts +91 -0
  467. package/src/tools/provider-execution.ts +70 -0
  468. package/src/tools/registry.ts +341 -0
  469. package/src/tools/types.ts +159 -0
  470. package/src/transport.ts +100 -0
  471. package/src/types.ts +1693 -0
  472. package/src/views.ts +164 -0
  473. package/src/widgets/design-system.ts +93 -0
  474. package/src/widgets/editor-appearance.ts +151 -0
  475. package/src/widgets/editor-material.ts +83 -0
  476. package/src/widgets/icon-set-registry.ts +105 -0
  477. package/src/widgets/index.ts +71 -0
  478. package/src/widgets/inspector-widgets/AlignmentGrid.tsx +182 -0
  479. package/src/widgets/inspector-widgets/AssetSlotPicker.tsx +123 -0
  480. package/src/widgets/inspector-widgets/BorderEditor.tsx +309 -0
  481. package/src/widgets/inspector-widgets/ColorPicker.tsx +549 -0
  482. package/src/widgets/inspector-widgets/CurveEditor.tsx +359 -0
  483. package/src/widgets/inspector-widgets/FilterEditor.tsx +108 -0
  484. package/src/widgets/inspector-widgets/FontPicker.tsx +191 -0
  485. package/src/widgets/inspector-widgets/GradientEditor.tsx +623 -0
  486. package/src/widgets/inspector-widgets/ScrubbableInput.tsx +180 -0
  487. package/src/widgets/inspector-widgets/ShadowEditor.tsx +319 -0
  488. package/src/widgets/inspector-widgets/color-utils.ts +201 -0
  489. package/src/widgets/inspector-widgets/curve-utils.ts +212 -0
  490. package/src/widgets/inspector-widgets/index.ts +25 -0
  491. package/src/widgets/inspector-widgets/shared.tsx +140 -0
  492. package/src/widgets/interactive-edit-scope.ts +33 -0
  493. package/src/widgets/patterns/Dialog.tsx +140 -0
  494. package/src/widgets/patterns/Fields.tsx +44 -0
  495. package/src/widgets/patterns/List.tsx +25 -0
  496. package/src/widgets/patterns/StateSurface.tsx +40 -0
  497. package/src/widgets/patterns/Surfaces.tsx +122 -0
  498. package/src/widgets/patterns/Tabs.tsx +80 -0
  499. package/src/widgets/patterns/Toolbar.tsx +72 -0
  500. package/src/widgets/patterns/Tree.tsx +72 -0
  501. package/src/widgets/primitives/AnchoredMenu.tsx +260 -0
  502. package/src/widgets/primitives/Button.tsx +62 -0
  503. package/src/widgets/primitives/ColorInput.tsx +78 -0
  504. package/src/widgets/primitives/DraftTextInput.tsx +63 -0
  505. package/src/widgets/primitives/EditorIcon.tsx +157 -0
  506. package/src/widgets/primitives/FormControls.tsx +88 -0
  507. package/src/widgets/primitives/HoverPreview.tsx +96 -0
  508. package/src/widgets/primitives/JsonInput.tsx +113 -0
  509. package/src/widgets/primitives/Layout.tsx +100 -0
  510. package/src/widgets/primitives/Menu.tsx +161 -0
  511. package/src/widgets/primitives/NumberInput.tsx +169 -0
  512. package/src/widgets/primitives/Panel.tsx +80 -0
  513. package/src/widgets/primitives/SectionHeader.tsx +77 -0
  514. package/src/widgets/primitives/Text.tsx +54 -0
  515. package/src/widgets/primitives/ThemeRootPortal.tsx +52 -0
  516. package/src/widgets/primitives/Tooltip.tsx +204 -0
  517. package/src/widgets/primitives/Vec3Input.tsx +70 -0
  518. package/src/widgets/primitives/banner-tones.ts +32 -0
  519. package/src/widgets/primitives/clamp-to-viewport.ts +44 -0
  520. package/src/widgets/primitives/editor-icons.ts +254 -0
  521. package/src/widgets/primitives/panel-header-styles.ts +42 -0
  522. package/src/widgets/theme.ts +2841 -0
  523. package/src/widgets/z-index.ts +25 -0
@@ -0,0 +1,402 @@
1
+ import { Button, bg, border, danger, radius, TextArea, text } from '@volter/sdk/widgets';
2
+ import { useState, useSyncExternalStore } from 'react';
3
+ import type { EditorAction } from '../action-registry';
4
+ import { registerDocumentOpener } from '@volter/sdk/kit/document-open-registry';
5
+ import {
6
+ getProjectTools,
7
+ projectToolsVersion,
8
+ refreshProjectTools,
9
+ runProjectTool,
10
+ subscribeProjectTools,
11
+ } from '@volter/sdk/kit/project-tools';
12
+ import {
13
+ getDocumentToolContributions,
14
+ getGlobalToolContributions,
15
+ getToolContributionLoadFailures,
16
+ subscribeToolContributions,
17
+ } from '../tool-loader';
18
+ import { waitUntil } from '@volter/sdk/kit/wait-until';
19
+ import {
20
+ activeWorkspaceDocumentId,
21
+ openWorkspaceDocument,
22
+ type WorkspaceDocumentContentProps,
23
+ } from '@volter/sdk/kit/workspace-document-registry';
24
+ import { registerWorkspaceDocumentRestorer } from '@volter/sdk/kit/workspace-document-restore';
25
+ import { openToolDocument } from './tool-documents';
26
+ import { defaultValueForSchema, ToolSchemaForm } from './tool-schema-form';
27
+
28
+ export const PROJECT_TOOLS_DOCUMENT_ID = 'project-tools';
29
+ export const PROJECT_TOOL_DOCUMENT_PREFIX = 'project-tool:';
30
+
31
+ function projectToolDocumentId(name: string): string {
32
+ return `${PROJECT_TOOL_DOCUMENT_PREFIX}${name}`;
33
+ }
34
+
35
+ export function openProjectToolsDocument(): void {
36
+ openWorkspaceDocument({
37
+ id: PROJECT_TOOLS_DOCUMENT_ID,
38
+ title: 'Project Tools',
39
+ kind: 'project-tool',
40
+ workspaceRole: 'workspace-reference',
41
+ Content: ProjectToolDocumentContent,
42
+ closeable: true,
43
+ presentation: () => ({ kind: 'workspace', id: PROJECT_TOOLS_DOCUMENT_ID }),
44
+ // The catalog is always truthfully reopenable — it lists whatever the
45
+ // project declares now — so it persists with no state of its own.
46
+ persist: () => ({ catalog: true }),
47
+ });
48
+ }
49
+
50
+ export function openProjectToolDocument(
51
+ name: string,
52
+ ): boolean {
53
+ const tool = getProjectTools().tools.find((entry) => entry.name === name);
54
+ if (!tool) return false;
55
+ const contributions = getDocumentToolContributions().filter((item) => item.tool?.name === name);
56
+ if (contributions.length === 1) return openToolDocument(contributions[0]!.id);
57
+ openWorkspaceDocument({
58
+ id: projectToolDocumentId(name),
59
+ title: tool.summary || tool.name,
60
+ kind: 'project-tool',
61
+ workspaceRole: 'workspace-reference',
62
+ provenance: { sourcePath: tool.sourcePath, origin: tool.name },
63
+ Content: ProjectToolDocumentContent,
64
+ closeable: true,
65
+ presentation: () => ({ kind: 'project-tool', name }),
66
+ persist: () => ({ name }),
67
+ });
68
+ return true;
69
+ }
70
+
71
+ /**
72
+ * THE TWO ADDRESSES THIS MODULE ANSWERS (`document-open-registry.ts`), each
73
+ * the other half of a `presentation()` above: the CATALOG is a workspace
74
+ * document (`{ kind: 'workspace', id: 'project-tools' }`), one named tool is
75
+ * its own kind (`{ kind: 'project-tool', name }`). Registered at module load,
76
+ * the shape `packages/editor-game/src/three/story-documents/three-story-documents.tsx:239`
77
+ * uses; the presenter addresses both without importing this file.
78
+ */
79
+ registerDocumentOpener<{ readonly id: string }>({
80
+ id: 'workspace',
81
+ owner: 'project-tool-documents',
82
+ // Every other workspace id belongs to the host's own workspace-document
83
+ // registry, or to the account document's opener.
84
+ open: (_store, request) => {
85
+ if (request.id !== PROJECT_TOOLS_DOCUMENT_ID) return null;
86
+ openProjectToolsDocument();
87
+ return PROJECT_TOOLS_DOCUMENT_ID;
88
+ },
89
+ });
90
+
91
+ registerDocumentOpener<{ readonly name: string }>({
92
+ id: 'project-tool',
93
+ owner: 'project-tool-documents',
94
+ // `openProjectToolDocument` answers a boolean because it opens one of TWO
95
+ // documents — a single matching contribution's own tool document, or the
96
+ // generic runner — and the active id is which one it chose. That is exactly
97
+ // what the presenter read here before this was an address.
98
+ open: (_store, request) =>
99
+ openProjectToolDocument(request.name) ? activeWorkspaceDocumentId() : null,
100
+ // The catalog is discovered asynchronously, so a durable address routinely
101
+ // names a tool before the project's tools have been read. Settling is the
102
+ // same refresh this kind's RESTORER prepares with (below), then the wait the
103
+ // presenter used to run as a poll around `open` itself.
104
+ settle: async (request) => {
105
+ await refreshProjectTools().catch(() => {});
106
+ if (await waitUntil(() => getProjectTools().tools.some((t) => t.name === request.name))) return;
107
+ throw new Error(`Project tool is not registered: ${request.name}`);
108
+ },
109
+ });
110
+
111
+ /** Reopen a persisted project-tool document: the catalog, or one registered
112
+ * callable's generic runner. The runner is self-verifying against the
113
+ * discovered catalog (`false` for a tool that is gone), which this kind's
114
+ * `prepare` has settled first. */
115
+ registerWorkspaceDocumentRestorer({
116
+ kind: 'project-tool',
117
+ owner: 'project-tool-documents',
118
+ prepare: () =>
119
+ refreshProjectTools().then(
120
+ () => {},
121
+ () => {},
122
+ ),
123
+ restore: ({ state }) => {
124
+ const record = state as { catalog?: unknown; name?: unknown } | null | undefined;
125
+ if (record?.catalog === true) {
126
+ openProjectToolsDocument();
127
+ return true;
128
+ }
129
+ return typeof record?.name === 'string' && openProjectToolDocument(record.name);
130
+ },
131
+ });
132
+
133
+ export function buildProjectToolActions(): EditorAction[] {
134
+ return [
135
+ {
136
+ id: 'project-tools:open',
137
+ label: 'Open Project Tools',
138
+ category: 'action',
139
+ execute: () => openProjectToolsDocument(),
140
+ },
141
+ ...getProjectTools().tools.map((tool) => ({
142
+ id: `project-tool:${tool.name}`,
143
+ label: `Run: ${tool.summary || tool.name}`,
144
+ category: 'action' as const,
145
+ execute: () => void openProjectToolDocument(tool.name),
146
+ })),
147
+ ];
148
+ }
149
+
150
+ function JsonBlock({ value }: { value: unknown }) {
151
+ return <pre style={jsonStyle}>{JSON.stringify(value, null, 2)}</pre>;
152
+ }
153
+
154
+ export function ProjectToolDocumentContent({ documentId }: WorkspaceDocumentContentProps) {
155
+ useSyncExternalStore(subscribeProjectTools, projectToolsVersion);
156
+ useSyncExternalStore(subscribeToolContributions, getGlobalToolContributions);
157
+ const snapshot = getProjectTools();
158
+ const toolName = documentId.startsWith(PROJECT_TOOL_DOCUMENT_PREFIX)
159
+ ? documentId.slice(PROJECT_TOOL_DOCUMENT_PREFIX.length)
160
+ : null;
161
+ const tool = toolName ? snapshot.tools.find((entry) => entry.name === toolName) : null;
162
+ if (!toolName) {
163
+ return (
164
+ <div style={rootStyle} data-testid="project-tools-catalog">
165
+ <h2 style={headingStyle}>Project Tools</h2>
166
+ <p style={{ ...mutedStyle, margin: '0 0 18px', maxWidth: 720, lineHeight: 1.5 }}>
167
+ Explicitly registered in <code>package.json#volter.tools</code>. Each tool is an ordinary
168
+ project function; a registration may pair it with optional editor contributions.
169
+ </p>
170
+ <div style={{ display: 'grid', gap: 8 }}>
171
+ {snapshot.tools.map((entry) => (
172
+ <Button
173
+ key={entry.name}
174
+ variant="ghost"
175
+ className="volter-project-tool-card"
176
+ onClick={() => openProjectToolDocument(entry.name)}
177
+ data-testid={`project-command-card:${entry.name}`}
178
+ >
179
+ <span style={cardTitleRowStyle}>
180
+ <strong style={{ color: text[1], fontWeight: 600 }}>{entry.summary}</strong>
181
+ <span style={openLabelStyle}>Open</span>
182
+ </span>
183
+ <code style={{ color: text[2], fontSize: 'var(--volter-font-sm)' }}>{entry.name}</code>
184
+ <span style={cardMetaRowStyle}>
185
+ <span>
186
+ {entry.host} · {entry.permission.risk} · {entry.sourcePath}
187
+ </span>
188
+ </span>
189
+ </Button>
190
+ ))}
191
+ </div>
192
+ {snapshot.tools.length === 0 && snapshot.loadErrors.length === 0 && (
193
+ <div style={mutedStyle}>No project tools registered.</div>
194
+ )}
195
+ {snapshot.loadErrors.map((error) => (
196
+ <div key={`${error.sourcePath}:${error.message}`} style={errorStyle}>
197
+ {error.sourcePath}: {error.message}
198
+ </div>
199
+ ))}
200
+ {/* The server's `loadErrors` cover the CALLABLES it imported in node;
201
+ contributions are only scanned there and imported in the tab, so a
202
+ contribution that throws on import can appear nowhere else on this
203
+ page — which is how a standing document went invisibly absent. */}
204
+ {getToolContributionLoadFailures().map((failure) => (
205
+ <div key={`${failure.entryPath}:${failure.error}`} style={errorStyle}>
206
+ {failure.entryPath}: {failure.error}
207
+ </div>
208
+ ))}
209
+ </div>
210
+ );
211
+ }
212
+
213
+ if (!tool) {
214
+ return <div style={rootStyle}>This tool is no longer available.</div>;
215
+ }
216
+
217
+ return <ProjectToolRunner key={tool.name} tool={tool} />;
218
+ }
219
+
220
+ function ProjectToolRunner({
221
+ tool,
222
+ }: {
223
+ tool: ReturnType<typeof getProjectTools>['tools'][number];
224
+ }) {
225
+ const presentations = getDocumentToolContributions().filter(
226
+ (item) => item.tool?.name === tool.name,
227
+ );
228
+ const initial = defaultValueForSchema(tool.inputSchema);
229
+ const [input, setInput] = useState<Record<string, unknown>>(
230
+ initial && typeof initial === 'object' && !Array.isArray(initial)
231
+ ? (initial as Record<string, unknown>)
232
+ : {},
233
+ );
234
+ const [rawText, setRawText] = useState(() => JSON.stringify(input, null, 2));
235
+ const [result, setResult] = useState<unknown>(null);
236
+ const [running, setRunning] = useState(false);
237
+ const [inputError, setInputError] = useState<string | null>(null);
238
+
239
+ const runnable = tool.host === 'node';
240
+ const execute = async () => {
241
+ const confirm =
242
+ tool.permission.risk === 'read' ||
243
+ window.confirm(`${tool.permission.summary}\n\nRun ${tool.name}?`);
244
+ if (!confirm) return;
245
+ setRunning(true);
246
+ try {
247
+ setResult(await runProjectTool(tool.name, input, { confirm: true }));
248
+ } catch (error) {
249
+ setResult({ ok: false, error: { code: 'REQUEST_FAILED', message: String(error) } });
250
+ } finally {
251
+ setRunning(false);
252
+ }
253
+ };
254
+
255
+ return (
256
+ <div style={rootStyle} data-testid={`project-tool:${tool.name}`}>
257
+ <h2 style={headingStyle}>{tool.summary}</h2>
258
+ <code style={{ color: text[2] }}>{tool.name}</code>
259
+ <p style={{ color: text[2] }}>{tool.description}</p>
260
+ <div style={mutedStyle}>
261
+ {tool.host} · {tool.permission.risk} · {tool.sourcePath}
262
+ </div>
263
+ {presentations.length > 0 && (
264
+ <section style={{ marginTop: 18, maxWidth: 760 }}>
265
+ <h3 style={{ margin: '0 0 8px', fontSize: 13 }}>Presentations</h3>
266
+ <div style={{ display: 'grid', gap: 8 }}>
267
+ {presentations.map((presentation) => (
268
+ <Button
269
+ key={presentation.id}
270
+ variant="ghost"
271
+ className="volter-project-tool-card"
272
+ onClick={() => openToolDocument(presentation.id)}
273
+ >
274
+ <span style={cardTitleRowStyle}>
275
+ <strong style={{ color: text[1], fontWeight: 600 }}>{presentation.title}</strong>
276
+ <span style={openLabelStyle}>Open</span>
277
+ </span>
278
+ </Button>
279
+ ))}
280
+ </div>
281
+ </section>
282
+ )}
283
+ {!runnable && (
284
+ <div style={errorStyle}>
285
+ This runner supports Node-hosted tools. Import the underlying function directly in browser
286
+ or runtime code.
287
+ </div>
288
+ )}
289
+ <details open={presentations.length === 0} style={{ marginTop: 18, maxWidth: 760 }}>
290
+ <summary style={{ cursor: 'pointer', color: text[2], fontSize: 12 }}>
291
+ {presentations.length > 0 ? 'Advanced · invoke native schema' : 'Input'}
292
+ </summary>
293
+ <section style={{ marginTop: 12 }}>
294
+ <ToolSchemaForm
295
+ schema={tool.inputSchema}
296
+ value={input}
297
+ onChange={(next) => {
298
+ setInput(next);
299
+ setRawText(JSON.stringify(next, null, 2));
300
+ setInputError(null);
301
+ }}
302
+ />
303
+ </section>
304
+ {inputError && <div style={errorStyle}>{inputError}</div>}
305
+ <Button
306
+ variant="primary"
307
+ disabled={!runnable || running || inputError !== null}
308
+ aria-busy={running}
309
+ onClick={() => void execute()}
310
+ style={{ marginTop: 16 }}
311
+ >
312
+ {running ? 'Running…' : 'Run tool'}
313
+ </Button>
314
+ <details style={{ marginTop: 16 }}>
315
+ <summary style={labelStyle}>Advanced JSON</summary>
316
+ <TextArea
317
+ id={`tool-input:${tool.name}`}
318
+ value={rawText}
319
+ onChange={(event) => {
320
+ const nextText = event.target.value;
321
+ setRawText(nextText);
322
+ try {
323
+ const parsed = JSON.parse(nextText) as unknown;
324
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
325
+ throw new Error('Input must be a JSON object.');
326
+ }
327
+ setInput(parsed as Record<string, unknown>);
328
+ setInputError(null);
329
+ } catch (error) {
330
+ setInputError(error instanceof Error ? error.message : String(error));
331
+ }
332
+ }}
333
+ rows={10}
334
+ data-variant="code"
335
+ style={textareaStyle}
336
+ />
337
+ <details>
338
+ <summary style={labelStyle}>Input schema</summary>
339
+ <JsonBlock value={tool.inputSchema} />
340
+ </details>
341
+ </details>
342
+ </details>
343
+ {result !== null && (
344
+ <section>
345
+ <div style={labelStyle}>Result</div>
346
+ <JsonBlock value={result} />
347
+ </section>
348
+ )}
349
+ </div>
350
+ );
351
+ }
352
+
353
+ const rootStyle: React.CSSProperties = {
354
+ width: '100%',
355
+ maxWidth: 960,
356
+ margin: '0 auto',
357
+ padding: 24,
358
+ boxSizing: 'border-box',
359
+ overflow: 'auto',
360
+ pointerEvents: 'auto',
361
+ color: text[1],
362
+ fontSize: 'var(--volter-font-base)',
363
+ };
364
+ const headingStyle: React.CSSProperties = { margin: '0 0 6px', fontSize: 20 };
365
+ const mutedStyle: React.CSSProperties = { color: text[2], fontSize: 'var(--volter-font-sm)' };
366
+ const labelStyle: React.CSSProperties = { display: 'block', margin: '14px 0 6px', color: text[1] };
367
+ const cardTitleRowStyle: React.CSSProperties = {
368
+ display: 'flex',
369
+ width: '100%',
370
+ alignItems: 'center',
371
+ justifyContent: 'space-between',
372
+ gap: 12,
373
+ };
374
+ const openLabelStyle: React.CSSProperties = {
375
+ color: text[2],
376
+ fontSize: 'var(--volter-font-sm)',
377
+ fontWeight: 500,
378
+ };
379
+ const cardMetaRowStyle: React.CSSProperties = {
380
+ display: 'flex',
381
+ width: '100%',
382
+ minWidth: 0,
383
+ alignItems: 'center',
384
+ justifyContent: 'space-between',
385
+ gap: 12,
386
+ color: text[2],
387
+ fontSize: 'var(--volter-font-sm)',
388
+ };
389
+ const errorStyle: React.CSSProperties = { marginTop: 10, color: danger, whiteSpace: 'pre-wrap' };
390
+ const textareaStyle: React.CSSProperties = {
391
+ width: '100%',
392
+ boxSizing: 'border-box',
393
+ resize: 'vertical',
394
+ };
395
+ const jsonStyle: React.CSSProperties = {
396
+ overflow: 'auto',
397
+ padding: 10,
398
+ background: bg.inset,
399
+ border: `1px solid ${border[1]}`,
400
+ borderRadius: radius.sm,
401
+ color: text[2],
402
+ };
@@ -0,0 +1,221 @@
1
+ /** Scene-table navigation delegates rendering to installed document owners. */
2
+ import { openRegisteredDocument } from '@volter/sdk/kit/document-open-registry';
3
+ import { shellStoreForHost } from '@volter/sdk/kit/shell-store-door';
4
+ import { projectAdapterFacet, type ResolvedDocumentTable, subscribeProjectAdapter } from '@volter/sdk/kit/project-adapter';
5
+ import { planSceneDocument, sceneTabRow } from '@volter/sdk/kit/scene-document-plan';
6
+ import { openAvailableWorkspaceDocument } from '@volter/sdk/kit/workspace-available-documents';
7
+ import { activateWorkspaceDocument, setWorkspaceDocumentTitle } from '@volter/sdk/kit/workspace-document-registry';
8
+ import { rootDocumentId } from '../world-document-routing';
9
+ import { kindDocumentId, openKindDocument } from './kind-documents';
10
+
11
+ export function reconcileSceneDocuments(table: ResolvedDocumentTable | null): void {
12
+ if (!table) return;
13
+ for (const row of sceneTabRow(table)) {
14
+ if (row.plan.kind !== 'root-document') continue;
15
+ const id = rootDocumentId(row.plan.regionId);
16
+ if (id) setWorkspaceDocumentTitle(id, row.plan.title);
17
+ }
18
+ }
19
+ export function startSceneDocuments(): () => void {
20
+ const run = () => reconcileSceneDocuments(projectAdapterFacet()?.scenes ?? null);
21
+ run();
22
+ return subscribeProjectAdapter(run);
23
+ }
24
+
25
+ export interface SceneOpenRefusal {
26
+ readonly ok: false;
27
+ readonly code:
28
+ | 'SCENE_TABLE_UNAVAILABLE'
29
+ | 'SCENE_NOT_FOUND'
30
+ | 'SCENE_NOT_OPENABLE'
31
+ /** Reached ONLY through the running game's own navigation, and no game is
32
+ * running here. Distinct from `SCENE_NOT_OPENABLE` because it is not a
33
+ * dead end: starting the game makes it openable (`scene-live-open.ts`). */
34
+ | 'SCENE_NAVIGATION_NOT_RUNNING'
35
+ | 'SCENE_DOCUMENT_NOT_MOUNTED';
36
+ readonly error: string;
37
+ readonly known?: readonly string[];
38
+ }
39
+
40
+ export type SceneOpenResult =
41
+ | { readonly ok: true; readonly documentId: string; readonly title: string }
42
+ | SceneOpenRefusal;
43
+
44
+ /**
45
+ * OPEN one piece of the adapter's scene table by id — the Edit half of the
46
+ * table's `open` verb, and the same verb for a scene, a prefab, or a story
47
+ * state (ARCHITECTURE-CORE §Editor: "any other piece … opens as a sibling
48
+ * document through the same verb").
49
+ *
50
+ * Every refusal is CODED because the classes are graded differently: a table
51
+ * that has not loaded is a session fact, an unknown id is a caller error, an
52
+ * unopenable entry is the GAME's own declaration (quoted verbatim), and a
53
+ * document the host has not mounted is a host gap. Prose alone cannot separate
54
+ * them.
55
+ */
56
+ /**
57
+ * How long {@link openSceneTableEntryWhenListed} will wait for the project
58
+ * adapter's table before refusing.
59
+ *
60
+ * MEASURED, not chosen: three cold the editor's `edit` command sessions on a
61
+ * `--template models` probe, opening `model:src/models/cube.blend` in a poll
62
+ * loop from the moment the tab connected — **6025 ms, 6831 ms, 6474 ms**, and
63
+ * in all three the first refusal was `SCENE_TABLE_UNAVAILABLE`, i.e. the
64
+ * adapter had not loaded at all. So for ~6.4 s after the editor reports
65
+ * "Editor ready" and the tab is present, the ONE general door for putting a
66
+ * document on screen answered "no". Every walk in the stage-transport unit
67
+ * had to wrap `editor.open` in a retry loop to get past it, and the frame
68
+ * hits the same window from the other side (WORK.md NEXT item 2).
69
+ *
70
+ * 15 s is that worst case with headroom for a slower box. It is a BOUND and
71
+ * not a fix for slowness: if opening a document ever legitimately needs
72
+ * longer than this, the thing to change is why, not this number.
73
+ */
74
+ const SCENE_TABLE_WAIT_MS = 15_000;
75
+
76
+ /**
77
+ * {@link openSceneTableEntry}, but WAITING for the adapter's table first.
78
+ *
79
+ * WHY THE WAIT CANNOT STOP AT THE FIRST RESOLUTION: a table resolves MORE
80
+ * THAN ONCE — a contributed finder (the mesh capability's models finder)
81
+ * registers after the first resolution and the table is resolved again with
82
+ * its entries — so "the adapter answered and your id is not in it" is not yet
83
+ * "your id does not exist". `kind-documents.tsx`'s `whenDocumentEntry` learned
84
+ * this on 2026-09-05 and has waited correctly ever since; this door never did,
85
+ * and that asymmetry IS the defect: two doors onto one table, one patient and
86
+ * one not.
87
+ *
88
+ * BOTH REFUSALS SURVIVE UNCHANGED. On timeout this returns exactly what the
89
+ * synchronous door would have returned at that moment — `SCENE_TABLE_UNAVAILABLE`
90
+ * if the adapter never loaded, `SCENE_NOT_FOUND` with the known ids if it did.
91
+ * The cost of the patience is paid by a genuinely unknown id, which now takes
92
+ * the full bound to be told so; that is the right side to lose on, because the
93
+ * alternative is the 2026-09-05 bug — refusing a document that was about to
94
+ * exist.
95
+ */
96
+ export async function openSceneTableEntryWhenListed(
97
+ id: string,
98
+ ): Promise<SceneOpenResult> {
99
+ const listed = (): boolean =>
100
+ projectAdapterFacet()?.scenes.entries.some((candidate) => candidate.id === id) ?? false;
101
+ if (!listed()) {
102
+ await new Promise<void>((resolve) => {
103
+ let done = false;
104
+ const finish = (): void => {
105
+ if (done) return;
106
+ done = true;
107
+ clearTimeout(timer);
108
+ stop();
109
+ resolve();
110
+ };
111
+ const timer = setTimeout(finish, SCENE_TABLE_WAIT_MS);
112
+ const stop = subscribeProjectAdapter(() => {
113
+ if (listed()) finish();
114
+ });
115
+ // The table can resolve between the check above and the subscribe.
116
+ if (listed()) finish();
117
+ });
118
+ }
119
+ return openSceneTableEntry(id);
120
+ }
121
+
122
+ export function openSceneTableEntry(id: string): SceneOpenResult {
123
+ const facet = projectAdapterFacet();
124
+ if (!facet) {
125
+ return {
126
+ ok: false,
127
+ code: 'SCENE_TABLE_UNAVAILABLE',
128
+ error: 'open: the project adapter has not loaded yet, so there is no scene table to open.',
129
+ };
130
+ }
131
+ const entry = facet.scenes.entries.find((candidate) => candidate.id === id);
132
+ if (!entry) {
133
+ const known = facet.scenes.entries.map((candidate) => candidate.id);
134
+ return {
135
+ ok: false,
136
+ code: 'SCENE_NOT_FOUND',
137
+ error: `open: "${id}" is not in the adapter's scene table. Known ids: ${
138
+ known.length > 0 ? known.join(', ') : '(the table is empty)'
139
+ }.`,
140
+ known,
141
+ };
142
+ }
143
+ // A KIND document (a model, a page — any entry a project contribution
144
+ // authors, `kind-documents.tsx`) is opened the way a Content double-click
145
+ // opens it. Before this, `open` fell through to the scene planner, which
146
+ // asked the entry for a region and refused it by name — so an agent had no
147
+ // door to put the model it was writing on screen (2026-09-06).
148
+ if (
149
+ entry.kind !== 'scene' &&
150
+ entry.kind !== 'prefab' &&
151
+ openKindDocument(entry, { activate: true })
152
+ ) {
153
+ return { ok: true, documentId: kindDocumentId(entry.id), title: entry.label };
154
+ }
155
+ const plan = planSceneDocument(entry);
156
+ switch (plan.kind) {
157
+ case 'no-document':
158
+ // A LIVE-REACHED scene is not a dead end — it is a scene this session
159
+ // cannot reach because nothing is running. The verb tries the live half
160
+ // FIRST (`command-listener.ts`), so arriving here means there was no
161
+ // game. ANY `liveReach` earns this code: the planner sets the field only
162
+ // for the reaches the live half actually OPENS (`scene-document-plan.ts`
163
+ // states which), so "present" and "start the game and ask again" are
164
+ // the same statement.
165
+ if (plan.liveReach !== undefined) {
166
+ return {
167
+ ok: false,
168
+ code: 'SCENE_NAVIGATION_NOT_RUNNING',
169
+ error: `open: ${plan.reason} No game is running in this session.`,
170
+ };
171
+ }
172
+ return {
173
+ ok: false,
174
+ code: 'SCENE_NOT_OPENABLE',
175
+ // The adapter's own sentence, unaltered — see `scene-document-plan.ts`.
176
+ error: `open: "${id}" has no Edit document — ${plan.reason}`,
177
+ };
178
+ case 'root-document': {
179
+ const documentId = rootDocumentId(plan.regionId);
180
+ if (!documentId) {
181
+ return {
182
+ ok: false,
183
+ code: 'SCENE_DOCUMENT_NOT_MOUNTED',
184
+ error: `open: "${id}" is region "${plan.regionId}"'s own document, and no document is mounted for that region in this session.`,
185
+ };
186
+ }
187
+ // Reopen the registered root document if its tab was closed.
188
+ openAvailableWorkspaceDocument(documentId) || activateWorkspaceDocument(documentId);
189
+ return { ok: true, documentId, title: plan.title };
190
+ }
191
+ case 'isolation-document': {
192
+ const documentId = openRegisteredDocument('scene', shellStoreForHost() ?? {}, { entry, activate: true });
193
+ return documentId
194
+ ? { ok: true, documentId, title: plan.title }
195
+ : { ok: false, code: 'SCENE_NOT_OPENABLE', error: `No installed scene editor can open "${id}".` };
196
+ }
197
+ case 'story-document': {
198
+ // The composed id is the whole address; resolving it, and saying WHICH
199
+ // way it failed, is the story kind's own job — it reports the specific
200
+ // reason (an id no composed story answers to, or a module whose medium
201
+ // is undeclared) to the session console, and this verb refuses with the
202
+ // one code the caller can act on.
203
+ const documentId = openRegisteredDocument('story', shellStoreForHost() ?? {}, {
204
+ storyId: plan.storyId,
205
+ title: plan.title,
206
+ });
207
+ if (documentId === null) {
208
+ return {
209
+ ok: false,
210
+ code: 'SCENE_DOCUMENT_NOT_MOUNTED',
211
+ error:
212
+ `open: "${id}" is reached by story "${plan.storyId}", and nothing in this editor ` +
213
+ "opened it — either this project's story registry does not hold that id, or its " +
214
+ 'module declares no medium (declare it via `editor/volter.adapter.ts` regionIncludes or a ' +
215
+ 'manifest root entry). The session console names which.',
216
+ };
217
+ }
218
+ return { ok: true, documentId, title: plan.title };
219
+ }
220
+ }
221
+ }