@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,58 @@
1
+ /**
2
+ * ENVIRONMENT IMAGES: panoramas a view can light by and draw behind the scene
3
+ * (`PreviewLighting.environment.image`), registered as data by the integration
4
+ * that ships them (a `*.environment.ts` contribution, point `workspace.environment`).
5
+ * A view names an image by id, never by URL: the URL is a built asset's, which a
6
+ * rebuild renames, and a saved view outlives the build that wrote it.
7
+ */
8
+
9
+ export interface EnvironmentImage {
10
+ readonly id: string;
11
+ readonly title: string;
12
+ /** The image as served: an equirectangular panorama in scene-referred light. */
13
+ readonly url: string;
14
+ readonly format: 'exr' | 'hdr';
15
+ }
16
+
17
+ /** What a `*.environment.ts` contribution exports as `environment`: one integration's images. */
18
+ export interface EnvironmentImageSet {
19
+ readonly id: string;
20
+ /** Where the images come from and under what terms, as the shipping integration states it. */
21
+ readonly source: string;
22
+ readonly images: readonly EnvironmentImage[];
23
+ }
24
+
25
+ const images = new Map<string, EnvironmentImage>();
26
+ const listeners = new Set<() => void>();
27
+
28
+ function changed(): void {
29
+ for (const listener of listeners) listener();
30
+ }
31
+
32
+ /** Register a set's images; returns the unregister. An id already registered is refused. */
33
+ export function registerEnvironmentImages(set: EnvironmentImageSet): () => void {
34
+ for (const image of set.images) {
35
+ if (images.has(image.id)) throw new Error(`registerEnvironmentImages: "${image.id}" is already registered.`);
36
+ }
37
+ for (const image of set.images) images.set(image.id, image);
38
+ changed();
39
+ return () => {
40
+ for (const image of set.images) if (images.get(image.id) === image) images.delete(image.id);
41
+ changed();
42
+ };
43
+ }
44
+
45
+ export function environmentImage(id: string): EnvironmentImage | null {
46
+ return images.get(id) ?? null;
47
+ }
48
+
49
+ export function environmentImages(): readonly EnvironmentImage[] {
50
+ return [...images.values()];
51
+ }
52
+
53
+ export function subscribeEnvironmentImages(listener: () => void): () => void {
54
+ listeners.add(listener);
55
+ return () => {
56
+ listeners.delete(listener);
57
+ };
58
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Eyedropper session (D3.d) — a module-level subscribable singleton bridging the
3
+ * C1 `ColorPicker` (mounted inside the Inspector panel) and the canvas
4
+ * (`RootSelectionOverlay`), the two SIBLING React trees a "click the eyedropper
5
+ * button, then click somewhere on the canvas" gesture must cross when the native
6
+ * `EyeDropper` API is unavailable (the FALLBACK path this whole module exists
7
+ * for — see `ColorPicker.tsx`'s `handleEyedropper` and the `ColorSampleProvider`
8
+ * contract doc comment for why the native path needs none of this: it samples
9
+ * real rendered pixels itself).
10
+ *
11
+ * Mirrors `world-session-state.ts`'s "bare module singleton" shape, but keeps
12
+ * its OWN subscriber list (rather than piggybacking on `EditorShellStore.
13
+ * notifyIngestEdit`) since this is transient cross-panel UI state, not an
14
+ * authored/session toggle any editor-store snapshot needs to carry.
15
+ *
16
+ * Only ONE fallback pick can be in flight at a time — beginning a new one
17
+ * silently supersedes whatever was pending (mirrors the ColorPicker's own
18
+ * "one popover at a time" assumption; nothing today opens two eyedroppers at
19
+ * once).
20
+ */
21
+
22
+ export type EyedropperApply = (color: string | null) => void;
23
+
24
+ let activeApply: EyedropperApply | null = null;
25
+ const listeners = new Set<() => void>();
26
+
27
+ function notify(): void {
28
+ for (const l of listeners) l();
29
+ }
30
+
31
+ /** Begin a fallback eyedropper session — `apply` is the widget's own
32
+ * sampled-color callback, called exactly once when the session resolves
33
+ * (`null` color means "cancelled", e.g. Escape — never a fabricated color). */
34
+ export function beginEyedropperSession(apply: EyedropperApply): void {
35
+ activeApply = apply;
36
+ notify();
37
+ }
38
+
39
+ /** True while a fallback session is awaiting a canvas click/Escape. */
40
+ export function isEyedropperSessionActive(): boolean {
41
+ return activeApply !== null;
42
+ }
43
+
44
+ /** Resolve the active session with a sampled color (or `null` to cancel),
45
+ * then close it. A no-op if no session is active. */
46
+ export function resolveEyedropperSession(color: string | null): void {
47
+ const apply = activeApply;
48
+ if (!apply) return;
49
+ activeApply = null;
50
+ notify();
51
+ apply(color);
52
+ }
53
+
54
+ /** Subscribe to session begin/end transitions — `RootSelectionOverlay` binds
55
+ * this via `useSyncExternalStore` so it re-renders (shows/hides the cursor
56
+ * swatch) the instant a session starts or ends. */
57
+ export function subscribeEyedropperSession(listener: () => void): () => void {
58
+ listeners.add(listener);
59
+ return () => listeners.delete(listener);
60
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * THE PROJECT'S FILES, WRITTEN THROUGH THE WORKBENCH — the provider it
3
+ * installs here, and the window before it lands.
4
+ *
5
+ * `EditorHost.files` is the door (`packages/sdk/src/kit/files/`) —
6
+ * read/readBytes/write/exists/list/watch over PROJECT-RELATIVE paths, the same
7
+ * spelling the history door hands over, so both resolve against one workspace
8
+ * folder.
9
+ *
10
+ * WHAT THE PROVIDER BUYS, measured (U5): a volter write the workbench did not
11
+ * make is an EXTERNAL change to it — Monaco reloads the file,
12
+ * `modelService.updateModel` pushes a fresh text element through `EditStack`,
13
+ * and `IUndoRedoService.pushElement` clears that resource's FUTURE, so a gizmo
14
+ * drag's redo was lost whenever a text model for that file was open. A write
15
+ * made THROUGH the workbench is the workbench's own, so no reload fires and
16
+ * the future survives. That is what this buys, and nothing else.
17
+ *
18
+ * IT ARRIVES AFTER THE MOUNT, always: a `ServicesAccessor` is valid only for
19
+ * the synchronous part of a command, so the contribution cannot build the
20
+ * provider before the mount it is handed to. Until it does, the door falls
21
+ * back to the session's transports — a write in that window is a real write
22
+ * with nowhere else to go.
23
+ */
24
+ import type { EditorHostFileEvent, EditorHostFileProvider } from '@volter/sdk/host';
25
+
26
+ export type ProjectFileEvent = EditorHostFileEvent;
27
+ export type ProjectFileProvider = EditorHostFileProvider;
28
+
29
+ let provider: ProjectFileProvider | null = null;
30
+ const listeners = new Set<() => void>();
31
+
32
+ /**
33
+ * Is the provider installed? False until it lands — later than the mount,
34
+ * because a `ServicesAccessor` is valid only for a command's synchronous part,
35
+ * so the contribution hands the provider over after the editor is running. In
36
+ * that window a caller reaches the session's transports instead, which is a
37
+ * real write with nowhere else to go rather than a refusal.
38
+ */
39
+ export function filesProviderInstalled(): boolean {
40
+ return provider !== null;
41
+ }
42
+
43
+ /** The installed provider, or `null` before it lands. */
44
+ export function filesProvider(): ProjectFileProvider | null {
45
+ return provider;
46
+ }
47
+
48
+ /**
49
+ * Install how the project's files are read and written, or `null` to withdraw
50
+ * it — the provider is the workbench's, and a workbench that went away takes
51
+ * it with it.
52
+ */
53
+ export function setFilesProvider(next: ProjectFileProvider | null): void {
54
+ if (provider === next) return;
55
+ provider = next;
56
+ for (const listener of listeners) listener();
57
+ }
58
+
59
+ export function subscribeFilesProvider(listener: () => void): () => void {
60
+ listeners.add(listener);
61
+ return () => listeners.delete(listener);
62
+ }
@@ -0,0 +1,270 @@
1
+ /**
2
+ * THE ONE FILE API over the open project, in PROJECT-RELATIVE paths — the
3
+ * editor's half of `@volter/sdk/host`'s `files` door (U5).
4
+ *
5
+ * Under the FRAME this is VS Code's `IFileService`/`ITextFileService` over the
6
+ * workspace folder, installed as a provider by the Code-OSS bridge. Under the
7
+ * HOST — standalone the editor's `edit` command, and the hosted browser build — it is today's
8
+ * transports, and this module is the ONE place that says which transport owns
9
+ * which path. That statement used to be spread across five files' doc
10
+ * comments; it is written down once, here, because the fragmentation is the
11
+ * fact U5 measured:
12
+ *
13
+ * | path class | the session's route |
14
+ * |-----------------------|------------------------------|
15
+ * | read, anything | Vite `/@fs/<root>/<path>` |
16
+ * | write `public/**` | `POST /__editor/save-file` |
17
+ * | write `.volter/**` | `POST /__editor/volter-file` |
18
+ * | write `src/**` source | `POST /__ui-source/apply` | the storage source-write backend |
19
+ * | list `public/**` | `GET /__editor/assets` | StorageBackend |
20
+ * | watch | `EventSource /__editor/events` | StorageBackend.watch |
21
+ *
22
+ * A path class with no host transport is REFUSED BY NAME, naming the route
23
+ * that does own it. It is not this door's business to invent a general
24
+ * project-root write route on the session: each of those routes is
25
+ * deliberately narrow (`/__editor/volter-file` accepts only `.volter/**`,
26
+ * `/__editor/data-file` only `src/data/**\/*.data.json`), and their own header
27
+ * comments record that as defence in depth. Under the frame the question does
28
+ * not arise — the workbench's file service owns the whole folder.
29
+ *
30
+ * `StorageBackend`'s paths are NOT this door's paths, and that difference is
31
+ * the measurement the door exists for: `HttpStorage` is rooted at
32
+ * `<project>/public/` while a project-rooted backend is rooted at the
33
+ * project root. Callers that still speak `StorageBackend` keep doing so; what
34
+ * they get under the frame is `storage/host-files-storage.ts`, a `public/`
35
+ * view onto this door.
36
+ */
37
+
38
+ import { bytesToBase64 } from '@volter/sdk/kit/bytes-codec';
39
+ import { getProjectDefinePath } from '../editor-mode';
40
+ import { assertEditorServerAnswered, editorServerJson } from '@volter/sdk/kit/editor-server-response';
41
+ import { sourceMutationAttribution } from '@volter/sdk/kit/editor-session-attribution';
42
+ import { filesProvider, filesProviderInstalled, type ProjectFileEvent } from './file-provider';
43
+
44
+ const BASE = '/__editor';
45
+
46
+ export interface ProjectFileEntry {
47
+ readonly name: string;
48
+ readonly path: string;
49
+ readonly type: 'file' | 'dir';
50
+ }
51
+
52
+ /** Project-relative, `/`-separated, no leading slash, no `..`. */
53
+ function normalize(path: string): string {
54
+ return path.replace(/\\/g, '/').replace(/^\/+/, '').replace(/\/+$/, '');
55
+ }
56
+
57
+ function assertContained(path: string): string {
58
+ const normalized = normalize(path);
59
+ if (!normalized || normalized.split('/').includes('..')) {
60
+ throw new Error(`projectFiles: "${path}" is not a project-relative path.`);
61
+ }
62
+ return normalized;
63
+ }
64
+
65
+ /**
66
+ * The same containment check for a DIRECTORY, where the empty string is the
67
+ * project root and therefore legal.
68
+ *
69
+ * It exists because `list` ran bare {@link normalize} while every other member
70
+ * ran {@link assertContained} — so a `..` segment reached the frame's provider
71
+ * or a session route while the same segment in a `read` was refused here.
72
+ * `normalize` strips a LEADING slash; it has never removed a `..` segment, and
73
+ * a caller reading its name could be forgiven for thinking otherwise. The
74
+ * empty string is the one thing `assertContained` rejects that a directory
75
+ * legitimately needs (it is how the project root itself is listed), which is
76
+ * why this is a second function rather than a flag.
77
+ */
78
+ function assertContainedDir(dir: string): string {
79
+ const normalized = normalize(dir);
80
+ if (normalized.split('/').includes('..')) {
81
+ throw new Error(`projectFiles: "${dir}" is not a project-relative directory.`);
82
+ }
83
+ return normalized;
84
+ }
85
+
86
+ /**
87
+ * The refusal a host-tier write to a path class no session route owns gets.
88
+ * It NAMES the owning route rather than failing generically, because the one
89
+ * thing a caller can do about it is use that route.
90
+ */
91
+ function noHostWriteRoute(path: string): Error {
92
+ return new Error(
93
+ `projectFiles.write("${path}"): the standalone editor has no general project-root write route, ` +
94
+ 'and this door does not invent one. Source files are written through `/__ui-source/apply` ' +
95
+ '(`ui-source/source-write-backend.ts`), `public/**` through `/__editor/save-file`, `.volter/**` ' +
96
+ 'through `/__editor/volter-file`. Under the Code-OSS frame the workbench file service owns the ' +
97
+ 'whole folder and this refusal cannot occur.',
98
+ );
99
+ }
100
+
101
+ // ---------------------------------------------------------------------------
102
+ // The HOST fill — today's transports
103
+ // ---------------------------------------------------------------------------
104
+
105
+ async function hostRead(path: string): Promise<string> {
106
+ const res = await fetch(`/@fs/${getProjectDefinePath()}/${path}`);
107
+ if (!res.ok) throw new Error(`projectFiles.read "${path}": HTTP ${res.status}`);
108
+ return res.text();
109
+ }
110
+
111
+ async function hostReadBytes(path: string): Promise<Uint8Array> {
112
+ const res = await fetch(`/@fs/${getProjectDefinePath()}/${path}`);
113
+ if (!res.ok) throw new Error(`projectFiles.readBytes "${path}": HTTP ${res.status}`);
114
+ return new Uint8Array(await res.arrayBuffer());
115
+ }
116
+
117
+ async function hostWrite(path: string, data: string | Uint8Array): Promise<void> {
118
+ if (path.startsWith('public/')) {
119
+ const body =
120
+ typeof data === 'string'
121
+ ? { path: path.slice('public/'.length), content: data, ...sourceMutationAttribution() }
122
+ : {
123
+ path: path.slice('public/'.length),
124
+ content: bytesToBase64(data),
125
+ encoding: 'base64' as const,
126
+ ...sourceMutationAttribution(),
127
+ };
128
+ const res = await fetch(`${BASE}/save-file`, {
129
+ method: 'POST',
130
+ headers: { 'Content-Type': 'application/json' },
131
+ body: JSON.stringify(body),
132
+ });
133
+ assertEditorServerAnswered(res, `Write ${path} failed`);
134
+ if (!res.ok) throw new Error(`projectFiles.write "${path}": HTTP ${res.status}`);
135
+ return;
136
+ }
137
+ if (path.startsWith('.volter/')) {
138
+ const body =
139
+ typeof data === 'string'
140
+ ? { path, content: data, ...sourceMutationAttribution() }
141
+ : {
142
+ path,
143
+ content: bytesToBase64(data),
144
+ encoding: 'base64' as const,
145
+ ...sourceMutationAttribution(),
146
+ };
147
+ const res = await fetch(`${BASE}/volter-file`, {
148
+ method: 'POST',
149
+ headers: { 'Content-Type': 'application/json' },
150
+ body: JSON.stringify(body),
151
+ });
152
+ assertEditorServerAnswered(res, `Write ${path} failed`);
153
+ if (!res.ok) throw new Error(`projectFiles.write "${path}": HTTP ${res.status}`);
154
+ return;
155
+ }
156
+ throw noHostWriteRoute(path);
157
+ }
158
+
159
+ async function hostExists(path: string): Promise<boolean> {
160
+ try {
161
+ const res = await fetch(`/@fs/${getProjectDefinePath()}/${path}`, { method: 'HEAD' });
162
+ // The dev server's SPA fallback answers 200 with `index.html` for a missing
163
+ // path, so `res.ok` alone cannot tell existence from absence — the same
164
+ // measured false positive `api/project-source.ts`'s `probeProjectFile`
165
+ // records. A real file never answers as an HTML DOCUMENT.
166
+ if (!res.ok) return false;
167
+ return !(res.headers.get('content-type') ?? '').toLowerCase().includes('text/html');
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+
173
+ interface ServerAssetEntry {
174
+ name: string;
175
+ type: 'file' | 'directory';
176
+ }
177
+
178
+ async function hostList(dir: string): Promise<readonly ProjectFileEntry[]> {
179
+ if (!dir.startsWith('public')) {
180
+ throw new Error(
181
+ `projectFiles.list("${dir}"): the standalone editor lists only \`public/**\` ` +
182
+ '(`/__editor/assets`); source trees are listed by glob through ' +
183
+ "`/__editor/source-files` (`api/project-source.ts`'s `listProjectSourceFiles`).",
184
+ );
185
+ }
186
+ const inner = dir === 'public' ? '' : dir.slice('public/'.length);
187
+ const res = await fetch(`${BASE}/assets?${new URLSearchParams({ dir: inner })}`);
188
+ const { entries } = await editorServerJson<{ entries: ServerAssetEntry[] }>(
189
+ res,
190
+ `projectFiles.list "${dir}" failed`,
191
+ );
192
+ return entries.map((entry) => ({
193
+ name: entry.name,
194
+ path: inner ? `public/${inner}/${entry.name}` : `public/${entry.name}`,
195
+ type: entry.type === 'directory' ? ('dir' as const) : ('file' as const),
196
+ }));
197
+ }
198
+
199
+ function hostWatch(listener: (event: ProjectFileEvent) => void): () => void {
200
+ const source = new EventSource(`${BASE}/events`);
201
+ const handler = (ev: MessageEvent) => {
202
+ try {
203
+ const data = JSON.parse(ev.data) as { type?: string; file?: string; path?: string };
204
+ const path = data.path ?? data.file;
205
+ if (!path) return;
206
+ listener({
207
+ type: (data.type as ProjectFileEvent['type']) ?? 'update',
208
+ path: normalize(path),
209
+ });
210
+ } catch {
211
+ // Non-JSON keepalive frame.
212
+ }
213
+ };
214
+ source.addEventListener('message', handler);
215
+ return () => {
216
+ source.removeEventListener('message', handler);
217
+ source.close();
218
+ };
219
+ }
220
+
221
+ // ---------------------------------------------------------------------------
222
+ // The door
223
+ // ---------------------------------------------------------------------------
224
+
225
+ export const projectFiles = {
226
+ /** True while the workbench's own file service is answering. A caller with
227
+ * a transport of its own (the source-write lane) reads this to decide
228
+ * whether its write would be EXTERNAL to the workbench. */
229
+ frameOwned: filesProviderInstalled,
230
+
231
+ // Every door below `return await`s, never returns the promise bare. With a
232
+ // bare return this frame leaves V8's async stack, and a workbench file
233
+ // provider's rejection (`FileOperationError`) then carries ONLY workbench
234
+ // frames — the stack the console ledger reads to decide whether an error is
235
+ // the project's (`isWorkbenchOrigin`). A Play script's
236
+ // `await host.files.read('missing.json')` must keep its own frames on it.
237
+ async read(path: string): Promise<string> {
238
+ const key = assertContained(path);
239
+ return await (filesProvider()?.read(key) ?? hostRead(key));
240
+ },
241
+
242
+ async readBytes(path: string): Promise<Uint8Array> {
243
+ const key = assertContained(path);
244
+ const provider = filesProvider();
245
+ return await (provider?.readBytes ? provider.readBytes(key) : hostReadBytes(key));
246
+ },
247
+
248
+ async write(path: string, data: string | Uint8Array): Promise<void> {
249
+ const key = assertContained(path);
250
+ const provider = filesProvider();
251
+ if (provider) return await provider.write(key, data);
252
+ return await hostWrite(key, data);
253
+ },
254
+
255
+ async exists(path: string): Promise<boolean> {
256
+ const key = assertContained(path);
257
+ return await (filesProvider()?.exists(key) ?? hostExists(key));
258
+ },
259
+
260
+ async list(dir: string): Promise<readonly ProjectFileEntry[]> {
261
+ const key = assertContainedDir(dir);
262
+ const provider = filesProvider();
263
+ return await (provider?.list ? provider.list(key) : hostList(key));
264
+ },
265
+
266
+ watch(listener: (event: ProjectFileEvent) => void): () => void {
267
+ const provider = filesProvider();
268
+ return provider?.watch ? provider.watch(listener) : hostWatch(listener);
269
+ },
270
+ };
@@ -0,0 +1,137 @@
1
+ /**
2
+ * THE FINDER NAMESPACE — host-owned discovery algorithms an adapter SELECTS.
3
+ *
4
+ * ARCHITECTURE-CORE §The editor protocol, "Zero inference": what zero
5
+ * inference forbids is the ENGINE running a finder nobody selected. A
6
+ * convention (`src/scenes/`, a story registration) is legitimate exactly when
7
+ * it is an adapter's declared finder parameter, and illegitimate as implicit
8
+ * engine behavior.
9
+ *
10
+ * That is enforced MECHANICALLY, not by policy: everything under this
11
+ * directory has exactly ONE sanctioned importer — the editor's adapter loader
12
+ * (`packages/sdk/src/kit/project-adapter.ts`) — and
13
+ * `packages/engine/test/finder-import-boundary.test.ts` fails by name when any
14
+ * other engine/editor file imports it. Do not add a second importer; make the
15
+ * loader answer instead.
16
+ *
17
+ * Dependency direction is one-way: finders import their parameter types from
18
+ * `../adapter-module`, and `adapter-module.ts` imports nothing from here. That
19
+ * is what keeps a game's `editor/volter.adapter.ts` free of finder implementations.
20
+ */
21
+
22
+ import {
23
+ EXPORTED_COMPOSITION_REGIONS,
24
+ type FinderSelection,
25
+ type ScenesFromEntrypointSelectionParams,
26
+ } from '@volter/project/adapter/adapter-module';
27
+ import type { FinderResult } from '@volter/project/adapter/finders/finder-result';
28
+ import { registerFinder, runRegisteredFinder } from '@volter/project/adapter/finders/registry';
29
+ import { type ZodType, z } from 'zod';
30
+ import {
31
+ type ScenesFromEntrypointSelectionInput,
32
+ scenesFromEntrypointSelection,
33
+ } from './scenes-from-entrypoint-selection';
34
+
35
+ export type { FinderResult } from '@volter/project/adapter/finders/finder-result';
36
+ export type {
37
+ FinderContribution,
38
+ FinderRegistration,
39
+ } from '@volter/project/adapter/finders/registry';
40
+ export {
41
+ finderReadsSources,
42
+ registerContributedFinder,
43
+ registeredFinderNames,
44
+ registerFinder,
45
+ runRegisteredFinder,
46
+ } from '@volter/project/adapter/finders/registry';
47
+ export type {
48
+ EntrypointSource,
49
+ ScenesFromEntrypointSelectionInput,
50
+ } from './scenes-from-entrypoint-selection';
51
+ export { scenesFromEntrypointSelection } from './scenes-from-entrypoint-selection';
52
+
53
+ /** Everything any shipped finder can be handed, gathered once by the loader. */
54
+ /** A project source the host read for a selection's `include` globs. */
55
+ export interface ProjectSourceFile {
56
+ /** Project-relative path. */
57
+ readonly path: string;
58
+ readonly source: string;
59
+ }
60
+
61
+ /** One entry of the host's project component index. */
62
+ export interface ProjectComponentRef {
63
+ readonly name: string;
64
+ /** Project-relative source path of the component's own module. */
65
+ readonly path: string;
66
+ /** Region this component's surface belongs to, when the host knows it. */
67
+ readonly region?: string | null;
68
+ }
69
+
70
+ export type FinderInput = ScenesFromEntrypointSelectionInput & {
71
+ /**
72
+ * The project's component index — what a finder joins its own discovery
73
+ * against (a prefab's source path and region).
74
+ *
75
+ * There is deliberately no `stories` here. `prefabsFromStories` used to be
76
+ * an engine finder whose story registrations the EDITOR filled, which is how
77
+ * the editor's adapter loader came to import the story registry and, through
78
+ * it, Storybook. It is a registered finder that reads its own ledger now
79
+ * (`packages/sdk/src/kit/stories/prefabs-finder.ts`): a finder's data arrives
80
+ * with the finder.
81
+ */
82
+ readonly components?: readonly ProjectComponentRef[];
83
+ /** The sources matching every selection's `include` globs — empty when
84
+ * no selection declares any. A contributed finder reads the project
85
+ * through this and {@link FinderInput.files} and nothing else. */
86
+ readonly sources?: readonly ProjectSourceFile[];
87
+ /**
88
+ * The PATHS matching those same globs — every one of them, including the
89
+ * files `sources` has no text for.
90
+ *
91
+ * A finder over BINARY documents needs this and could not use `sources`:
92
+ * `@volter/editor-blender`'s `modelsFromBlendFiles` lists `.blend` files, and there
93
+ * is nothing in a `.blend` a text walk could honestly read — the entry IS
94
+ * the file. Handing it a decoded binary instead would have been the shim.
95
+ */
96
+ readonly files?: readonly string[];
97
+ };
98
+
99
+ /**
100
+ * Run one adapter-declared selection. The switch is exhaustive over
101
+ * {@link FinderSelection}: a new finder that forgets a case fails to COMPILE
102
+ * here rather than silently contributing nothing.
103
+ */
104
+ export function runFinderSelection(selection: FinderSelection, input: FinderInput): FinderResult {
105
+ return runRegisteredFinder(selection, input);
106
+ }
107
+
108
+ // The engine's own finders register here, schemas beside them: what an
109
+ // adapter may select by name is exactly what this registry holds.
110
+ const ScenesFromEntrypointSelectionSchema = z
111
+ .object({
112
+ finder: z.literal('scenesFromEntrypointSelection'),
113
+ regions: z
114
+ .union([z.array(z.string().min(1)).min(1), z.literal(EXPORTED_COMPOSITION_REGIONS)])
115
+ .describe('Region ids whose entrypoints carry the selection, or the rule form'),
116
+ selection: z
117
+ .string()
118
+ .min(1)
119
+ .optional()
120
+ .describe(
121
+ "Identifier of the entrypoint's module-level scene selection table; omit for a " +
122
+ 'single-composition entrypoint',
123
+ ),
124
+ })
125
+ .strict()
126
+ .refine((value) => value.selection === undefined || Array.isArray(value.regions), {
127
+ message:
128
+ 'scenesFromEntrypointSelection: `selection` names an identifier in ONE entrypoint’s ' +
129
+ `source, so it cannot be paired with the \`${EXPORTED_COMPOSITION_REGIONS}\` rule — ` +
130
+ 'name the region explicitly (`regions: ["<rootId>"]`).',
131
+ });
132
+ registerFinder<ScenesFromEntrypointSelectionParams, FinderInput>({
133
+ name: 'scenesFromEntrypointSelection',
134
+ schema:
135
+ ScenesFromEntrypointSelectionSchema as unknown as ZodType<ScenesFromEntrypointSelectionParams>,
136
+ run: scenesFromEntrypointSelection,
137
+ });