@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,171 @@
1
+ /**
2
+ * B8.4 — pure math for the Asset Lab compare mode (the editor's `screenshot
3
+ * <model.glb> --compare <ref.glb>` command): silhouette masks, IoU, the overlay pixel recipe,
4
+ * forward-facing normalization, and the equal-height placement that lets a
5
+ * procedural humanoid be scored numerically against a reference GLB.
6
+ *
7
+ * Deliberately DOM/WebGL-free so the whole scoring contract is unit-testable
8
+ * in node (`packages/editor/test/asset-compare-core.test.ts`); the browser
9
+ * rendering half lives in `asset-compare.ts`.
10
+ */
11
+
12
+ export const ASSET_COMPARE_VIEWS = ['front', 'side'] as const;
13
+ export type AssetCompareView = (typeof ASSET_COMPARE_VIEWS)[number];
14
+
15
+ /** Both models are scaled to this height, feet at y=0, centered on x=z=0. */
16
+ export const COMPARE_TARGET_HEIGHT = 1;
17
+ /** Fixed orthographic frame: half-height around the model's mid-height. The
18
+ * 10% margin keeps equal-height silhouettes fully in frame while wasting
19
+ * little resolution — and, being CONSTANT, makes captures deterministic
20
+ * across runs (a stated gate) and comparable across assets. */
21
+ export const COMPARE_FRAME_HALF_HEIGHT = 0.55;
22
+ export const COMPARE_FRAME_CENTER_Y = COMPARE_TARGET_HEIGHT / 2;
23
+
24
+ /** Silhouettes render as a flat unlit white override on solid black, so the
25
+ * mask threshold sits mid-range — antialiased edge pixels land on the side
26
+ * of the ramp they dominate. */
27
+ export const SILHOUETTE_LUMA_THRESHOLD = 128;
28
+
29
+ /** Overlay legend (RGB). The overlay is machine-generated review evidence:
30
+ * every pixel is exactly one of these four colors. */
31
+ export const OVERLAY_BACKGROUND_RGB = [24, 26, 31] as const;
32
+ export const OVERLAY_ASSET_ONLY_RGB = [235, 137, 52] as const; // orange — the asset under test
33
+ export const OVERLAY_REF_ONLY_RGB = [56, 189, 248] as const; // cyan — the reference
34
+ export const OVERLAY_OVERLAP_RGB = [236, 240, 238] as const; // near-white — agreement
35
+
36
+ /**
37
+ * Binary silhouette mask from RGBA pixels of a white-on-black render: a
38
+ * pixel belongs to the silhouette when any color channel crosses the
39
+ * threshold. Returns one byte (0|1) per pixel.
40
+ */
41
+ export function silhouetteMaskFromRgba(rgba: ArrayLike<number>, pixelCount: number): Uint8Array {
42
+ if (rgba.length < pixelCount * 4) {
43
+ throw new Error(
44
+ `Silhouette mask expected ${pixelCount * 4} RGBA bytes but received ${rgba.length}.`,
45
+ );
46
+ }
47
+ const mask = new Uint8Array(pixelCount);
48
+ for (let pixel = 0; pixel < pixelCount; pixel++) {
49
+ const offset = pixel * 4;
50
+ const value =
51
+ rgba[offset]! >= SILHOUETTE_LUMA_THRESHOLD ||
52
+ rgba[offset + 1]! >= SILHOUETTE_LUMA_THRESHOLD ||
53
+ rgba[offset + 2]! >= SILHOUETTE_LUMA_THRESHOLD;
54
+ mask[pixel] = value ? 1 : 0;
55
+ }
56
+ return mask;
57
+ }
58
+
59
+ export interface MaskOverlapStats {
60
+ intersection: number;
61
+ union: number;
62
+ aCount: number;
63
+ bCount: number;
64
+ /** intersection / union; 0 when the union is empty (guard emptiness upstream). */
65
+ iou: number;
66
+ }
67
+
68
+ /** Silhouette intersection-over-union between two same-length binary masks. */
69
+ export function maskIoU(a: Uint8Array, b: Uint8Array): MaskOverlapStats {
70
+ if (a.length !== b.length) {
71
+ throw new Error(`Mask IoU requires equal-size masks (${a.length} vs ${b.length}).`);
72
+ }
73
+ let intersection = 0;
74
+ let aCount = 0;
75
+ let bCount = 0;
76
+ for (let index = 0; index < a.length; index++) {
77
+ const inA = a[index] !== 0;
78
+ const inB = b[index] !== 0;
79
+ if (inA) aCount++;
80
+ if (inB) bCount++;
81
+ if (inA && inB) intersection++;
82
+ }
83
+ const union = aCount + bCount - intersection;
84
+ return { intersection, union, aCount, bCount, iou: union === 0 ? 0 : intersection / union };
85
+ }
86
+
87
+ /**
88
+ * The compare overlay: both silhouettes on one image in visibly distinct
89
+ * colors — asset-only orange, reference-only cyan, agreement near-white on a
90
+ * dark background. Returns opaque RGBA bytes ready for an ImageData.
91
+ */
92
+ export function overlayRgba(
93
+ assetMask: Uint8Array,
94
+ refMask: Uint8Array,
95
+ ): Uint8ClampedArray<ArrayBuffer> {
96
+ if (assetMask.length !== refMask.length) {
97
+ throw new Error(
98
+ `Overlay requires equal-size masks (${assetMask.length} vs ${refMask.length}).`,
99
+ );
100
+ }
101
+ const out = new Uint8ClampedArray(assetMask.length * 4);
102
+ for (let pixel = 0; pixel < assetMask.length; pixel++) {
103
+ const inAsset = assetMask[pixel] !== 0;
104
+ const inRef = refMask[pixel] !== 0;
105
+ const color =
106
+ inAsset && inRef
107
+ ? OVERLAY_OVERLAP_RGB
108
+ : inAsset
109
+ ? OVERLAY_ASSET_ONLY_RGB
110
+ : inRef
111
+ ? OVERLAY_REF_ONLY_RGB
112
+ : OVERLAY_BACKGROUND_RGB;
113
+ const offset = pixel * 4;
114
+ out[offset] = color[0];
115
+ out[offset + 1] = color[1];
116
+ out[offset + 2] = color[2];
117
+ out[offset + 3] = 255;
118
+ }
119
+ return out;
120
+ }
121
+
122
+ /** A structurally valid forward vector ([x,y,z], finite, non-degenerate in
123
+ * the ground plane) or null — used to read GLB `extras`/`userData.forward`
124
+ * without trusting arbitrary content. */
125
+ export function parseForwardVector(value: unknown): [number, number, number] | null {
126
+ if (!Array.isArray(value) || value.length !== 3) return null;
127
+ const [x, y, z] = value as unknown[];
128
+ if (typeof x !== 'number' || typeof y !== 'number' || typeof z !== 'number') return null;
129
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)) return null;
130
+ if (Math.hypot(x, z) < 1e-6) return null; // vertical/zero forward cannot define a facing
131
+ return [x, y, z];
132
+ }
133
+
134
+ /**
135
+ * The Y rotation (radians) that turns a model whose forward is `forward`
136
+ * to face +Z — the direction the fixed front camera looks from. Facing is a
137
+ * ground-plane property; the vector's y component is ignored.
138
+ */
139
+ export function forwardYawRadians(forward: readonly [number, number, number]): number {
140
+ const [x, , z] = forward;
141
+ if (!Number.isFinite(x) || !Number.isFinite(z) || Math.hypot(x, z) < 1e-6) {
142
+ throw new Error(`Cannot derive a facing from forward vector [${forward.join(', ')}].`);
143
+ }
144
+ return Math.atan2(x, z);
145
+ }
146
+
147
+ export interface NormalizedPlacement {
148
+ scale: number;
149
+ /** Applied AFTER the scale: ground at y=0, footprint centered at x=z=0. */
150
+ position: [number, number, number];
151
+ }
152
+
153
+ /**
154
+ * Bounding-box height normalization (the decided compare framing): scale the
155
+ * model so its bounds stand `targetHeight` tall, then place it with its
156
+ * ground plane at y=0 and its bounds center on the x=0/z=0 axis.
157
+ */
158
+ export function normalizedPlacement(
159
+ min: readonly [number, number, number],
160
+ max: readonly [number, number, number],
161
+ targetHeight: number = COMPARE_TARGET_HEIGHT,
162
+ ): NormalizedPlacement {
163
+ const height = max[1] - min[1];
164
+ if (!Number.isFinite(height) || height <= 0) {
165
+ throw new Error(`Compare normalization needs positive model height, got ${height}.`);
166
+ }
167
+ const scale = targetHeight / height;
168
+ const centerX = (min[0] + max[0]) / 2;
169
+ const centerZ = (min[2] + max[2]) / 2;
170
+ return { scale, position: [-centerX * scale, -min[1] * scale, -centerZ * scale] };
171
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Context contributed by the active typed Asset Editor to the existing editor
3
+ * shell. Asset documents own content; the workspace owns placement. Keeping
4
+ * this as a tiny external store lets the status bar and the workspace's
5
+ * inspection surface resolution know WHICH document is active without an
6
+ * Asset Editor recreating those panes inside the center.
7
+ *
8
+ * It carries FACTS ONLY — id, title, type, status. Never markup: an open
9
+ * asset document is a SUBJECT PRODUCER, and what it produces goes through the
10
+ * one composer into the one inspector box like everything else. A React node
11
+ * put on this store would be a second, invisible way for a document to render
12
+ * somewhere else, and there is exactly one.
13
+ */
14
+
15
+ import { useSyncExternalStore } from 'react';
16
+ import { createHmrRegistrationGroup, type HmrRegistrationContext } from '@volter/sdk/kit/hmr-registration-group';
17
+ import { registerWorkspaceStatus } from './workspace-status-registry';
18
+
19
+ export interface AssetEditorContextValue {
20
+ readonly documentId: string;
21
+ readonly title: string;
22
+ readonly type: string;
23
+ readonly status?: string;
24
+ }
25
+
26
+ interface ActiveAssetEditorContext extends AssetEditorContextValue {
27
+ readonly token: symbol;
28
+ }
29
+
30
+ let active: ActiveAssetEditorContext | null = null;
31
+ let version = 0;
32
+ const listeners = new Set<() => void>();
33
+
34
+ function notifyChanged(): void {
35
+ version++;
36
+ for (const listener of listeners) listener();
37
+ }
38
+
39
+ export function subscribeAssetEditorContext(listener: () => void): () => void {
40
+ listeners.add(listener);
41
+ return () => listeners.delete(listener);
42
+ }
43
+
44
+ export function assetEditorContextVersion(): number {
45
+ return version;
46
+ }
47
+
48
+ export function getActiveAssetEditorContext(): AssetEditorContextValue | null {
49
+ return active;
50
+ }
51
+
52
+ /** Activate one document contribution. The returned disposer only clears the
53
+ * exact activation it created, so an older tab unmount cannot erase a newer
54
+ * active tab's context. */
55
+ export function activateAssetEditorContext(value: AssetEditorContextValue): () => void {
56
+ const token = Symbol(value.documentId);
57
+ active = { ...value, token };
58
+ notifyChanged();
59
+ return () => {
60
+ if (active?.token !== token) return;
61
+ active = null;
62
+ notifyChanged();
63
+ };
64
+ }
65
+
66
+ export function AssetEditorStatus() {
67
+ useSyncExternalStore(subscribeAssetEditorContext, assetEditorContextVersion);
68
+ const context = getActiveAssetEditorContext();
69
+ return context?.status ? (
70
+ <span className="volter-status-copy" data-testid="status-asset-editor" data-status-tone="muted">
71
+ {context.status}
72
+ </span>
73
+ ) : null;
74
+ }
75
+
76
+ const registrationGroup = createHmrRegistrationGroup(
77
+ // Vite's HMR context when a dev server serves this module; the SDK carries no bundler types.
78
+ (import.meta as ImportMeta & { hot?: HmrRegistrationContext }).hot,
79
+ 'asset-editor-shell-contributions',
80
+ );
81
+
82
+ export function ensureAssetEditorShellContributionsRegistered(): void {
83
+ registrationGroup.ensure((track) => {
84
+ track(
85
+ registerWorkspaceStatus({
86
+ id: 'asset-editor-status',
87
+ name: 'Asset editor',
88
+ align: 'left',
89
+ order: 40,
90
+ Content: AssetEditorStatus,
91
+ }),
92
+ );
93
+ });
94
+ }
95
+
96
+ ensureAssetEditorShellContributionsRegistered();
97
+
98
+ export function __resetAssetEditorContextForTest(): void {
99
+ active = null;
100
+ notifyChanged();
101
+ }
@@ -0,0 +1,96 @@
1
+ import { connectEvents } from '@volter/sdk/kit/editor-api';
2
+ import { announceAssetReload } from '@volter/sdk/kit/project-asset-refresh';
3
+
4
+ export interface AssetMovedEvent {
5
+ oldPath: string;
6
+ newPath: string;
7
+ updatedFiles: string[];
8
+ }
9
+
10
+ export interface AssetsChangedEvent {
11
+ readonly paths?: readonly string[];
12
+ }
13
+
14
+ /**
15
+ * Connect to the editor server's SSE endpoint for asset events.
16
+ * Returns a cleanup function to disconnect.
17
+ */
18
+ export function connectAssetEvents(
19
+ onAssetMoved: (event: AssetMovedEvent) => void,
20
+ onAssetsChanged: (event: AssetsChangedEvent) => void = () => {},
21
+ ): () => void {
22
+ // Browser mode (Phase A2): no Node dev server / SSE. A rename can't be
23
+ // reconstructed from self-derived watch events — a move surfaces as an
24
+ // unlinked `remove` + `create` with no old→new pairing — so asset-move sync
25
+ // stays a server-only signal (revisit with A4's external-change detection).
26
+ const source = connectEvents();
27
+
28
+ source.addEventListener('asset-moved', (e: MessageEvent) => {
29
+ try {
30
+ const data = JSON.parse(e.data) as AssetMovedEvent;
31
+ onAssetMoved(data);
32
+ } catch {
33
+ /* ignore malformed events */
34
+ }
35
+ });
36
+ source.addEventListener('assets-changed', (event: MessageEvent) => {
37
+ let detail: AssetsChangedEvent;
38
+ try {
39
+ detail = JSON.parse(event.data) as AssetsChangedEvent;
40
+ } catch {
41
+ detail = {};
42
+ }
43
+ const paths =
44
+ detail.paths?.map((path) => `/${path.replace(/^\/?public\//, '').replace(/^\//, '')}`) ?? [];
45
+ announceAssetReload(paths);
46
+ onAssetsChanged(detail);
47
+ });
48
+
49
+ return () => source.close();
50
+ }
51
+
52
+ export function connectToolFileEvents(onChanged: () => void): () => void {
53
+ const source = connectEvents();
54
+ source.addEventListener('tool-files-changed', () => onChanged());
55
+ return () => source.close();
56
+ }
57
+
58
+ /** Root declarations affect project configuration and adapter capabilities. */
59
+ export function connectProjectDeclarationEvents(onChanged: () => void): () => void {
60
+ const source = connectEvents();
61
+ source.addEventListener('project-declarations-changed', onChanged);
62
+ return () => source.close();
63
+ }
64
+
65
+ /**
66
+ * Connect to the editor server's SSE endpoint for project STORY file
67
+ * add/unlink events (C3, spec §9). Mirrors `connectToolFileEvents` for
68
+ * `*.stories.tsx` / `*.stories.ts` anywhere under `src/` — the React hierarchy's
69
+ * `refreshProjectStories()` is a cheap full rescan, same discipline as
70
+ * `refreshProjectTools`.
71
+ */
72
+ /**
73
+ * The editor server's `source-files-changed`: any `src/` file that is neither
74
+ * a tool nor a story — the files contributed FINDERS read (a models project's
75
+ * `src/models/*.ts`). Carries the project-relative path; the browser lane
76
+ * cannot name one and reports `''`.
77
+ */
78
+ export function connectSourceFileEvents(onChanged: (path: string) => void): () => void {
79
+ const source = connectEvents();
80
+ source.addEventListener('source-files-changed', (event) => {
81
+ let path = '';
82
+ try {
83
+ path = String((JSON.parse((event as MessageEvent).data) as { path?: string }).path ?? '');
84
+ } catch {
85
+ /* a payload without a path still means "something changed" */
86
+ }
87
+ onChanged(path);
88
+ });
89
+ return () => source.close();
90
+ }
91
+
92
+ export function connectStoryFileEvents(onChanged: () => void): () => void {
93
+ const source = connectEvents();
94
+ source.addEventListener('story-files-changed', () => onChanged());
95
+ return () => source.close();
96
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The verbs an `asset.inspector` contribution offers for the asset it is
3
+ * currently showing — published BY the section, because the section is what
4
+ * knows.
5
+ *
6
+ * WHY NOT A STATIC EXPORT. The first shape of this was `export const
7
+ * actions(asset)`, resolved synchronously beside `match(asset)`. It could
8
+ * only filter on the path, while the section itself decides structurally —
9
+ * the Edit Mesh door imports the module and calls `build()` — so the panel
10
+ * and `inspect().quickActions` disagreed: measured 2026-09-03, every `src/**`
11
+ * script offered "Edit mesh" through the control API while the human saw the
12
+ * button on mesh modules alone. A verb the human cannot see is exactly what
13
+ * `editor.inspect()` promises never to report, so the declaration moved to
14
+ * where the answer is.
15
+ *
16
+ * The section calls `props.setActions(...)` when it knows (and `[]` when it
17
+ * knows the answer is no); this store keys the list by contribution and
18
+ * asset, so a stale answer for a previous selection can never be served, and
19
+ * bumps a version `inspection/use-active-inspection.ts` subscribes to, the
20
+ * same way the section registry does.
21
+ */
22
+ import type { ToolAssetInspectorAction } from '@volter/sdk/contributions';
23
+
24
+ interface Published {
25
+ readonly assetPath: string;
26
+ readonly actions: readonly ToolAssetInspectorAction[];
27
+ }
28
+
29
+ const published = new Map<string, Published>();
30
+ let version = 0;
31
+ const listeners = new Set<() => void>();
32
+
33
+ function changed(): void {
34
+ version += 1;
35
+ for (const listener of listeners) listener();
36
+ }
37
+
38
+ /** Publish (or clear) one contribution's verbs for the asset it is showing. */
39
+ export function setAssetInspectorActions(
40
+ contributionId: string,
41
+ assetPath: string,
42
+ actions: readonly ToolAssetInspectorAction[],
43
+ ): void {
44
+ const current = published.get(contributionId);
45
+ if (
46
+ current &&
47
+ current.assetPath === assetPath &&
48
+ current.actions.length === actions.length &&
49
+ current.actions.every((action, i) => action === actions[i])
50
+ ) {
51
+ return;
52
+ }
53
+ published.set(contributionId, { assetPath, actions });
54
+ changed();
55
+ }
56
+
57
+ /** Forget a contribution's verbs (its section unmounted). */
58
+ export function clearAssetInspectorActions(contributionId: string): void {
59
+ if (!published.delete(contributionId)) return;
60
+ changed();
61
+ }
62
+
63
+ /** Every verb published FOR this asset, in contribution registration order.
64
+ * A list published for a different asset is ignored rather than served. */
65
+ export function assetInspectorActionsFor(assetPath: string): readonly ToolAssetInspectorAction[] {
66
+ const out: ToolAssetInspectorAction[] = [];
67
+ for (const entry of published.values()) {
68
+ if (entry.assetPath !== assetPath) continue;
69
+ out.push(...entry.actions);
70
+ }
71
+ return out;
72
+ }
73
+
74
+ export function subscribeAssetInspectorActions(listener: () => void): () => void {
75
+ listeners.add(listener);
76
+ return () => listeners.delete(listener);
77
+ }
78
+
79
+ export function assetInspectorActionsVersion(): number {
80
+ return version;
81
+ }
82
+
83
+ /** Test seam, mirroring the other module-scope stores. */
84
+ export function __resetAssetInspectorActionsForTest(): void {
85
+ published.clear();
86
+ version = 0;
87
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * WHO DRAWS *THIS* SELECTED ASSET — the tenth registry in the family of
3
+ * `workspace-document-restore.ts` (a kind owns its persisted state),
4
+ * `document-open-registry.ts` (a kind owns how it opens),
5
+ * `chrome-slot-registry.ts` (the host owns the place, a package owns what
6
+ * sits there), `content-entry-source-registry.ts` (the host owns the Content
7
+ * scope, a package owns why a component is content),
8
+ * `authoring/design-time-mount-registry.ts`, `component-board-registry.ts`,
9
+ * `component-states-registry.ts` and `static-panel-presentation-registry.ts`.
10
+ * Here: the host owns the Inspector's asset SECTION — the thumbnail, the
11
+ * metadata rows, the tool sections, the empty state — and a package owns the
12
+ * body for an asset the host has no way to draw.
13
+ *
14
+ * WHY IT EXISTS. `components/asset-selection-section.tsx` opened with
15
+ * `if (asset.online) { … <OnlineAssetDetail/> … }` — the Inspector knowing
16
+ * that an asset can come from an external catalog, and importing that
17
+ * catalog's whole detail view (421 lines, plus the import-job ledger it
18
+ * writes) into every editor boot, a `models` build that has no catalog
19
+ * included (WORK.md §The open-source launch, the final audit's online-library
20
+ * row). The sibling of `contentEntryForComponent`: one question — "is there a
21
+ * registered body for this subject, and what is it" — asked of a registry
22
+ * instead of answered by a branch.
23
+ *
24
+ * THE SHAPE is transcribed from `content-entry-source-registry.ts` (register /
25
+ * list / subscribe, owner-replaces-owner for an HMR re-evaluation, a stable
26
+ * EMPTY array so a reader's `useSyncExternalStore` snapshot is stable). TWO
27
+ * deliberate differences:
28
+ * - NO per-registration `subscribe` to re-fan. A content SOURCE has a ledger
29
+ * that settles asynchronously; a viewer is a pure function of the asset
30
+ * the host already re-renders on. The registry's own change signal is all
31
+ * a reader needs, and a hook with nothing to subscribe to is a name that
32
+ * got built because it was named.
33
+ * - `match(asset)` IS THE WHOLE DISCRIMINATOR. The host never asks "is this
34
+ * online" again; it asks who claims the asset. First match wins, in
35
+ * registration order, so a build with no catalog package falls through to
36
+ * the host's own generic body — which is the answer it always gave for
37
+ * every asset that was not online.
38
+ *
39
+ * NOTHING REGISTERED IS A REAL ANSWER: the generic body, exactly as before.
40
+ */
41
+
42
+ import type { ComponentType } from 'react';
43
+ import type { SelectedAsset } from '@volter/sdk/kit/asset-selection';
44
+
45
+ export interface AssetSelectionViewerProps {
46
+ readonly asset: SelectedAsset;
47
+ }
48
+
49
+ export interface AssetSelectionViewer {
50
+ /** The viewer's id, in its own vocabulary. */
51
+ readonly id: string;
52
+ /** Which module registered it. Re-registering the same owner+id REPLACES. */
53
+ readonly owner: string;
54
+ /** Ascending; ties keep registration order. */
55
+ readonly order?: number;
56
+ /** Does this viewer claim the selected asset? The host asks; it never
57
+ * inspects the asset for a lane's own fields itself. */
58
+ readonly match: (asset: SelectedAsset) => boolean;
59
+ /** The Inspector body for a claimed asset, rendered INSTEAD of the host's
60
+ * generic one — the viewer owns everything below the section's frame,
61
+ * including any actions it wants. */
62
+ readonly View: ComponentType<AssetSelectionViewerProps>;
63
+ }
64
+
65
+ const _viewers: AssetSelectionViewer[] = [];
66
+ const listeners = new Set<() => void>();
67
+ let version = 0;
68
+
69
+ function publish(): void {
70
+ version++;
71
+ for (const listener of listeners) listener();
72
+ }
73
+
74
+ /** Install a viewer. Returns the teardown. */
75
+ export function registerAssetSelectionViewer(viewer: AssetSelectionViewer): () => void {
76
+ const stale = _viewers.findIndex((item) => item.owner === viewer.owner && item.id === viewer.id);
77
+ if (stale >= 0) _viewers.splice(stale, 1);
78
+ _viewers.push(viewer);
79
+ _viewers.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
80
+ publish();
81
+ return () => {
82
+ const at = _viewers.indexOf(viewer);
83
+ if (at < 0) return;
84
+ _viewers.splice(at, 1);
85
+ publish();
86
+ };
87
+ }
88
+
89
+ /** The first registered viewer that claims this asset, or `null` — "nobody
90
+ * registered a body for it", which is a real answer and never an error. */
91
+ export function assetSelectionViewerFor(asset: SelectedAsset): AssetSelectionViewer | null {
92
+ for (const viewer of _viewers) if (viewer.match(asset)) return viewer;
93
+ return null;
94
+ }
95
+
96
+ /** ONE subscription for the Inspector section. */
97
+ export function subscribeAssetSelectionViewers(listener: () => void): () => void {
98
+ listeners.add(listener);
99
+ return () => {
100
+ listeners.delete(listener);
101
+ };
102
+ }
103
+
104
+ export function assetSelectionViewersVersion(): number {
105
+ return version;
106
+ }
107
+
108
+ /** Test-only reset (mirrors the restore, open, chrome-slot, content-source,
109
+ * design-time-mount, component-board and static-panel registries'). */
110
+ export function __resetAssetSelectionViewersForTest(): void {
111
+ _viewers.length = 0;
112
+ publish();
113
+ }