@volter/sdk 0.0.0-stage → 0.5.203

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 +1166 -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 +317 -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 +403 -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,478 @@
1
+ /**
2
+ * WHICH PRODUCT OPENS THIS PROJECT — one declaration, one resolver.
3
+ *
4
+ * A PRODUCT is the running program (ARCHITECTURE-CORE §The target shape, rule
5
+ * 4): `@volter/game-editor` and `@volter/cyclotron` each stitch packages onto
6
+ * the editor kit in code and each carry a `bin`. **Which product runs is never
7
+ * a switch** — there is no `--product` flag, no id in the manifest, no setting,
8
+ * the same way a folder never names which VS Code opens it and a `.blend` never
9
+ * names Blender.
10
+ *
11
+ * So the resolution is a DEPENDENCY resolution, exactly as
12
+ * `assertEditorProjectInstalled` resolves `@volter/editor-core`: the project's
13
+ * `dependencies` ∪ `devDependencies` are read, each `@volter/*` among them is
14
+ * resolved from the project, and the one whose `package.json` carries
15
+ * `volter.product` is the product. A project's `package.json` naming a product as
16
+ * a devDependency is the person's convenience — what `npm run dev` launches —
17
+ * and not a rule about the project.
18
+ *
19
+ * NONE and TWO are both refusals by name, because either answer would otherwise
20
+ * be guessed. None prints the `npm install --save-dev` line for both products;
21
+ * two names both and says the project must resolve it, because a page runs one
22
+ * product and nothing here can pick.
23
+ *
24
+ * WHO CALLS THIS, and why twice. The CLI resolves to REFUSE EARLY and to hand
25
+ * the directory to the session; the session resolves to SERVE the product's
26
+ * entry and to REPORT it (`EditorState.product`), because what it is serving is
27
+ * its own fact. One function, one set of refusal texts.
28
+ */
29
+
30
+ import { existsSync, readFileSync } from 'node:fs';
31
+ import { createRequire } from 'node:module';
32
+ import { dirname, join } from 'node:path';
33
+ import { pathToFileURL } from 'node:url';
34
+
35
+ /** The manifest key a product declares. A DECLARATION, not a config: it says
36
+ * what this package IS so the CLI and the session can find its entry without
37
+ * running it (ARCHITECTURE-CORE §The target shape, rule 8). */
38
+ export const PRODUCT_DECLARATION_KEY = 'volter.product';
39
+
40
+ /** Light or dark — the two the workbench's own `ColorScheme` has plain names
41
+ * for, and the only two a product needs to state (a high-contrast scheme is a
42
+ * person's accessibility choice, never a product's declaration). */
43
+ export type ProductColorTheme = 'dark' | 'light';
44
+
45
+ /**
46
+ * THE WORKBENCH THIS PRODUCT IS, named as a published release.
47
+ *
48
+ * A product is the running program, and the program is the Code-OSS workbench
49
+ * its kit and its half were compiled INTO (ARCHITECTURE-CORE §The target
50
+ * shape: "one product number per release, pinning the fork, the kit, the API
51
+ * and its media"). So which release those bytes are is not a machine's setting
52
+ * and not a person's choice — it is what the product IS, declared beside
53
+ * `entry` and `colorTheme` and read without running anything (rule 8).
54
+ *
55
+ * A release runs on one platform, so a product that ships on several declares
56
+ * one release per platform, keyed the way a release names it
57
+ * (`{ "darwin-arm64": {…}, "linux-x64": {…}, "win32-x64": {…} }`), and this
58
+ * is the entry for the machine reading it. A single `{ release, tarballSha256 }`
59
+ * is a product with one platform.
60
+ *
61
+ * `release` is the tag `scripts/workbench/build-release.mjs --publish` cuts on
62
+ * the fork's own repository, `<product>-<fork sha 12>-<platform>`;
63
+ * `tarballSha256` is the pin, verified against the downloaded bytes before a
64
+ * single one of them is extracted. Both come out of that script's own
65
+ * `BUILD.json`, and it prints this block to paste.
66
+ *
67
+ * A machine that has already fetched it keeps it in `~/.volter/workbenches/<tag>`
68
+ * and a project that has one names it in `.volter/workbench.json`, so this is
69
+ * consulted exactly once per machine per release — see
70
+ * `workbench-locator.ts`'s `resolveWorkbenchForProject`.
71
+ */
72
+ export interface ProductWorkbench {
73
+ /** The GitHub Release tag on `volter-ai/code-oss`. */
74
+ readonly release: string;
75
+ /** The sha256 of that release's tarball asset, hex. */
76
+ readonly tarballSha256: string;
77
+ }
78
+
79
+ /** A product package, as everything outside it needs to know it. */
80
+ export interface ProductIdentity {
81
+ /** The package name — `@volter/game-editor`. */
82
+ readonly name: string;
83
+ /** Its version, reported beside the workbench by the editor's `status` command. */
84
+ readonly version: string;
85
+ /**
86
+ * The command a person types to run it — the ONE key of its package.json
87
+ * `bin` (`volter-game-editor`). Every message the kit writes about a verb
88
+ * names this, because the kit itself has no command of its own.
89
+ */
90
+ readonly command: string;
91
+ /** The name a person sees — `volter.product.displayName` (`Volter Game Editor`). */
92
+ readonly displayName: string;
93
+ /**
94
+ * `volter.product.upgrade: true` — its command has `upgrade [version]`
95
+ * (`@volter/sdk/session/project-upgrade`), so a pinned-engine refusal
96
+ * may tell a person to run it. Optional: a product that says nothing has none.
97
+ */
98
+ readonly upgrade?: boolean;
99
+ /**
100
+ * `volter.product.adapterRequired: true` — a project this product opens must have its own
101
+ * adapter module (`editor/volter.adapter.ts`), because the product's layout and document
102
+ * finders are declared there and the native default shows none of them. Such a product refuses
103
+ * a project without one. Optional: a product that says nothing opens it on the native default.
104
+ */
105
+ readonly adapterRequired?: boolean;
106
+ /** Its package root, absolute. */
107
+ readonly dir: string;
108
+ /**
109
+ * Its ONE source entry, package-relative and POSIX (`./src/index.ts`). That
110
+ * entry IS the product's frame entry: it composes and re-exports `mountVolter`,
111
+ * which is the name the fork's contribution reads off the served module.
112
+ */
113
+ readonly entry: string;
114
+ /**
115
+ * WHICH WAY ROUND THIS PRODUCT PAINTS, before one line of its code runs.
116
+ *
117
+ * Measured 2026-09-21 on both releases: the web workbench's FIRST PAINT is
118
+ * LIGHT (`workbenchThemeService.ts`, `this.settings.getPreferredColorScheme()
119
+ * ?? (isWeb ? ColorScheme.LIGHT : ColorScheme.DARK)`), so the product's
120
+ * opening cover — which paints in `--vscode-*` variables, as it must — was
121
+ * white for its whole life and flipped dark the instant the real theme
122
+ * landed. The supported door is `IWorkbenchConstructionOptions
123
+ * .initialColorTheme`, which is read out of the PAGE CONFIG, before any
124
+ * extension or setting is available; the session's proxy injects it
125
+ * (`packages/editor-core/server/frame-proxy.ts`).
126
+ *
127
+ * It is a DECLARATION and not a setting (ARCHITECTURE-CORE §The target
128
+ * shape, rule 8): it says what the product IS, the same way `entry` does, and
129
+ * it has to be readable without running the product because the proxy needs
130
+ * it before the product exists. A person's own `workbench.colorTheme` still
131
+ * wins on every open after the first — the workbench prefers its stored theme
132
+ * over this and only falls back here when it has none.
133
+ */
134
+ readonly colorTheme: ProductColorTheme;
135
+ /** WHICH WORKBENCH THIS PRODUCT IS — see {@link ProductWorkbench}. */
136
+ readonly workbench: ProductWorkbench | null;
137
+ /**
138
+ * The ONE LINE that installs this product and starts a project in it —
139
+ * `volter.product.install` (`npx @volter/cyclotron create my-game`). A limited view quotes
140
+ * it wherever it cannot do what the local editor does (its chat answers with it, and every
141
+ * route it does not carry names it), so it is a declaration read without running the product.
142
+ * An undeclared one is `npx <name> create my-game`, which is what every product's `create`
143
+ * verb accepts.
144
+ */
145
+ readonly install: string;
146
+ }
147
+
148
+ /** The install line a refusal quotes, for a project that already EXISTS. Both
149
+ * products, because a person choosing between them is choosing what they are
150
+ * building, not a flag. */
151
+ export const PRODUCT_INSTALL_LINES = [
152
+ ' npm install --save-dev @volter/cyclotron',
153
+ ' npm install --save-dev @volter/game-editor',
154
+ ] as const;
155
+
156
+ /**
157
+ * The create line a refusal or a help screen quotes, for a project that does
158
+ * not exist yet. CREATION IS THE PRODUCT'S (ARCHITECTURE-CORE §The target
159
+ * shape, rule 1): a product scaffolds the project it opens, declaring its own
160
+ * presets, and there is no create verb in the kit's CLI for either of them to
161
+ * be an alias of.
162
+ *
163
+ * This is the ONE place the two product names are spelled outside the products
164
+ * themselves; the CLI and the session quote it rather than keeping a copy.
165
+ */
166
+ export const PRODUCT_CREATE_LINES = [' npx @volter/editor-core create <name>'] as const;
167
+
168
+ interface ProductManifestShape {
169
+ private?: unknown;
170
+ name?: unknown;
171
+ version?: unknown;
172
+ bin?: unknown;
173
+ volter?: { product?: { entry?: unknown; colorTheme?: unknown; workbench?: unknown; displayName?: unknown; install?: unknown; upgrade?: unknown; adapterRequired?: unknown } };
174
+ }
175
+
176
+ const PRODUCT_COLOR_THEMES: readonly ProductColorTheme[] = ['dark', 'light'];
177
+
178
+ /**
179
+ * Read one product package's declaration, or `null` when the manifest is not a
180
+ * product's. Throws when it declares `volter.product` and the declaration is
181
+ * unusable — a half-written product must be named, never skipped.
182
+ */
183
+ export function readProductManifest(packageDir: string): ProductIdentity | null {
184
+ const manifestPath = join(packageDir, 'package.json');
185
+ let manifest: ProductManifestShape;
186
+ try {
187
+ manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as ProductManifestShape;
188
+ } catch {
189
+ return null;
190
+ }
191
+ const declared = manifest.volter?.product;
192
+ if (declared === undefined) return null;
193
+ const entry = declared.entry;
194
+ if (typeof entry !== 'string' || !entry.startsWith('./'))
195
+ throw new Error(
196
+ `${manifestPath} declares ${PRODUCT_DECLARATION_KEY} but its "entry" is ` +
197
+ `${JSON.stringify(entry)}. It must be a ./-relative module — the product's ONE source ` +
198
+ 'entry, which is also its frame entry (e.g. "./src/index.ts").',
199
+ );
200
+ const resolved = join(packageDir, entry);
201
+ if (!existsSync(resolved))
202
+ throw new Error(
203
+ `${manifestPath} declares ${PRODUCT_DECLARATION_KEY}.entry ${JSON.stringify(entry)}, ` +
204
+ `which does not exist (${resolved}).`,
205
+ );
206
+ const colorTheme = declared.colorTheme;
207
+ // REQUIRED, like `entry`, and for the same reason: a product that does not
208
+ // say which way round it paints gets the workbench's web default, which is
209
+ // LIGHT, and its cover is white until its real theme loads. There is no
210
+ // defensible default to invent here — a dark product and a light product are
211
+ // both ordinary — so an unstated one is named rather than guessed.
212
+ if (typeof colorTheme !== 'string' || !PRODUCT_COLOR_THEMES.includes(colorTheme as never))
213
+ throw new Error(
214
+ `${manifestPath} declares ${PRODUCT_DECLARATION_KEY} but its "colorTheme" is ` +
215
+ `${JSON.stringify(colorTheme)}. It must be ${PRODUCT_COLOR_THEMES.map((one) =>
216
+ JSON.stringify(one),
217
+ ).join(' or ')} — which way round this product paints, read before any of its code ` +
218
+ "runs so the workbench's first frame is already the product's own background.",
219
+ );
220
+ // REQUIRED, for the same reason as `entry`: the kit names verbs in every
221
+ // message it writes, and there is no command to name but the product's own.
222
+ const bin = manifest.bin;
223
+ const commands = bin !== null && typeof bin === 'object' ? Object.keys(bin) : [];
224
+ if (commands.length !== 1)
225
+ throw new Error(
226
+ `${manifestPath} declares ${PRODUCT_DECLARATION_KEY} but its "bin" names ` +
227
+ `${commands.length === 0 ? 'no command' : `${commands.length} commands`}. A product has ` +
228
+ 'exactly one command — the one every session message tells a person to run.',
229
+ );
230
+ const displayName = declared.displayName;
231
+ if (typeof displayName !== 'string' || displayName.trim() === '')
232
+ throw new Error(
233
+ `${manifestPath} declares ${PRODUCT_DECLARATION_KEY} but its "displayName" is ` +
234
+ `${JSON.stringify(displayName)}. It must be the name a person sees (e.g. "Volter Editor").`,
235
+ );
236
+ const name = typeof manifest.name === 'string' ? manifest.name : packageDir;
237
+ const install = declared.install;
238
+ if (install !== undefined && (typeof install !== 'string' || install.trim() === ''))
239
+ throw new Error(
240
+ `${manifestPath} declares ${PRODUCT_DECLARATION_KEY} but its "install" is ` +
241
+ `${JSON.stringify(install)}. It is the one line that installs this product and starts a ` +
242
+ `project (e.g. "npx ${name} create my-game"), or absent.`,
243
+ );
244
+ return {
245
+ name,
246
+ version: typeof manifest.version === 'string' ? manifest.version : 'unknown',
247
+ command: commands[0]!,
248
+ displayName,
249
+ upgrade: declared.upgrade === true,
250
+ adapterRequired: declared.adapterRequired === true,
251
+ dir: packageDir,
252
+ entry,
253
+ colorTheme: colorTheme as ProductColorTheme,
254
+ // A private source product may use an explicitly selected matching checkout.
255
+ // Public packages must always carry a downloadable, checksummed workbench.
256
+ workbench: manifest.private === true && declared.workbench === undefined
257
+ ? null : readProductWorkbench(manifestPath, declared.workbench),
258
+ install: typeof install === 'string' ? install.trim() : `npx ${name} create my-game`,
259
+ };
260
+ }
261
+
262
+ /** The sha256 a release pins its tarball with, as `BUILD.json` writes it. */
263
+ const SHA256_HEX = /^[0-9a-f]{64}$/;
264
+
265
+ /**
266
+ * REQUIRED, like `entry` and `colorTheme`, and for the sharpest reason of the
267
+ * three: a product that does not say which workbench it is cannot be INSTALLED
268
+ * — `npx @volter/<product> create <name>` on a machine with nothing else on it
269
+ * has no other way to find the bytes it runs in, and the person is left writing
270
+ * a path to a directory they would have to build first. There is no default to
271
+ * invent (the tag names a fork commit nobody can guess), so an unstated one is
272
+ * named rather than guessed.
273
+ */
274
+ function readProductWorkbench(manifestPath: string, declared: unknown): ProductWorkbench {
275
+ const example =
276
+ ' "volter": { "product": { "workbench": { "release": "<product>-<fork sha 12>-<platform>", ' +
277
+ '"tarballSha256": "<64 hex>" } } }\n' +
278
+ '`node scripts/workbench/build-release.mjs --publish --out <release dir>` cuts the release ' +
279
+ 'and prints exactly that block.';
280
+ if (typeof declared !== 'object' || declared === null || Array.isArray(declared))
281
+ throw new Error(
282
+ `${manifestPath} declares ${PRODUCT_DECLARATION_KEY} but its "workbench" is ` +
283
+ `${JSON.stringify(declared)}. A product IS the Code-OSS workbench it was compiled into, ` +
284
+ `so it names the published release those bytes are:\n${example}`,
285
+ );
286
+ const platforms = declared as Record<string, unknown>;
287
+ if (!('release' in platforms) && !('tarballSha256' in platforms)) {
288
+ const machine = `${process.platform}-${process.arch}`;
289
+ const declaredHere = platforms[machine];
290
+ if (declaredHere === undefined)
291
+ throw new Error(
292
+ `${manifestPath}'s ${PRODUCT_DECLARATION_KEY}.workbench declares releases for ` +
293
+ `${Object.keys(platforms).join(', ') || 'no platform'} and this machine is ${machine}. A ` +
294
+ "Code-OSS server package carries its own platform's node binary and native modules, so " +
295
+ `there is nothing this product can run in here until a ${machine} release is cut:\n` +
296
+ ` node scripts/workbench/build-release.mjs --product <id> --platform ${machine} --checkout <fork dir> --publish`,
297
+ );
298
+ return readPlatformWorkbench(manifestPath, declaredHere, example);
299
+ }
300
+ return readPlatformWorkbench(manifestPath, declared, example);
301
+ }
302
+
303
+ function readPlatformWorkbench(manifestPath: string, declared: unknown, example: string): ProductWorkbench {
304
+ if (typeof declared !== 'object' || declared === null || Array.isArray(declared))
305
+ throw new Error(
306
+ `${manifestPath}'s ${PRODUCT_DECLARATION_KEY}.workbench names ${JSON.stringify(declared)} ` +
307
+ `for this platform, which is not a release:\n${example}`,
308
+ );
309
+ const record = declared as Record<string, unknown>;
310
+ const extra = Object.keys(record).filter((key) => key !== 'release' && key !== 'tarballSha256');
311
+ if (extra.length > 0)
312
+ throw new Error(
313
+ `${manifestPath}'s ${PRODUCT_DECLARATION_KEY}.workbench carries ` +
314
+ `${extra.map((key) => `"${key}"`).join(', ')}, which this declaration has no meaning for. ` +
315
+ `It names the release and the pin, and nothing else:\n${example}`,
316
+ );
317
+ const release = record['release'];
318
+ if (typeof release !== 'string' || release.trim() === '')
319
+ throw new Error(
320
+ `${manifestPath}'s ${PRODUCT_DECLARATION_KEY}.workbench names no "release" — the GitHub ` +
321
+ `Release tag its workbench was published under:\n${example}`,
322
+ );
323
+ const tarballSha256 = record['tarballSha256'];
324
+ if (typeof tarballSha256 !== 'string' || !SHA256_HEX.test(tarballSha256))
325
+ throw new Error(
326
+ `${manifestPath}'s ${PRODUCT_DECLARATION_KEY}.workbench has tarballSha256 ` +
327
+ `${JSON.stringify(tarballSha256)}, which is not 64 hex characters. It is the PIN — the ` +
328
+ 'hash the downloaded tarball is checked against before a byte of it is extracted, so it ' +
329
+ `is never approximate:\n${example}`,
330
+ );
331
+ return { release, tarballSha256 };
332
+ }
333
+
334
+ /**
335
+ * A product's SHORT id — `@volter/cyclotron` → `cyclotron`.
336
+ *
337
+ * It is the product's own `product({ id })`, the directory its workbench half
338
+ * lives in (`packages/<id>/workbench`), the `--product` flag the overlay and the
339
+ * release build take, and what a release records in `BUILD.json`. One derivation
340
+ * rather than four literals: the package name is the only place the product is
341
+ * NAMED, and everything else is that name's last segment.
342
+ */
343
+ export function workbenchProductId(packageName: string): string {
344
+ return packageName.split('/').pop() ?? packageName;
345
+ }
346
+
347
+ /** A product's entry as a path relative to `fromDir`, POSIX — the spelling a
348
+ * Vite manifest key and a dev-server URL both use. */
349
+ export function productEntryPath(product: ProductIdentity, fromDir: string): string {
350
+ const absolute = join(product.dir, product.entry);
351
+ const prefix = fromDir.endsWith('/') ? fromDir : `${fromDir}/`;
352
+ const relative = absolute.startsWith(prefix) ? absolute.slice(prefix.length) : absolute;
353
+ return relative.split('\\').join('/');
354
+ }
355
+
356
+ /** Every `@volter/*` this project declares, in either section, sorted. */
357
+ function declaredVolterPackages(projectRoot: string): string[] {
358
+ let manifest: { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };
359
+ try {
360
+ manifest = JSON.parse(
361
+ readFileSync(join(projectRoot, 'package.json'), 'utf8'),
362
+ ) as typeof manifest;
363
+ } catch {
364
+ return [];
365
+ }
366
+ return Object.keys({ ...(manifest.dependencies ?? {}), ...(manifest.devDependencies ?? {}) })
367
+ .filter((name) => name.startsWith('@volter/'))
368
+ .sort();
369
+ }
370
+
371
+ /** Where a package resolves FROM THE PROJECT, or null when it is not installed. */
372
+ function locatePackage(projectRoot: string, name: string): string | null {
373
+ const require = createRequire(pathToFileURL(join(projectRoot, 'package.json')));
374
+ try {
375
+ return dirname(require.resolve(`${name}/package.json`));
376
+ } catch {
377
+ // No `./package.json` export: walk up from whatever the bare name resolves
378
+ // to, which is what a package with a strict export map leaves reachable.
379
+ try {
380
+ let dir = dirname(require.resolve(name));
381
+ for (;;) {
382
+ const candidate = join(dir, 'package.json');
383
+ try {
384
+ if ((JSON.parse(readFileSync(candidate, 'utf8')) as { name?: string }).name === name)
385
+ return dir;
386
+ } catch {
387
+ /* keep walking */
388
+ }
389
+ const parent = dirname(dir);
390
+ if (parent === dir) return null;
391
+ dir = parent;
392
+ }
393
+ } catch {
394
+ return null;
395
+ }
396
+ }
397
+ }
398
+
399
+ /**
400
+ * THE PACKAGES A PRODUCT COMPOSES — the `volter:contributions/<name>` imports of the product's
401
+ * entry (`package.json#volter.product.entry`), each resolved from the product's own install and
402
+ * declaring `package.json#volter.contributions`.
403
+ *
404
+ * COMPOSITIONS ARE CODE (ARCHITECTURE-CORE §The target shape, rule 8): that import IS the
405
+ * composition, so it is what is read. The product's `dependencies` are not: they also carry
406
+ * the packages a game's capabilities add (`add music` declares `@volter/editor-dawproject`,
407
+ * which the runtime image must hold), and reading every dependency that declares contributions
408
+ * as composed made the page load a capability's documents into every game, and from a checkout
409
+ * fetch them from a folder the game's server does not serve.
410
+ */
411
+ export function productComposedPackages(product: ProductIdentity): string[] {
412
+ let entry: string;
413
+ try {
414
+ const manifest = JSON.parse(readFileSync(join(product.dir, 'package.json'), 'utf8')) as {
415
+ volter?: { product?: { entry?: unknown } };
416
+ };
417
+ const path = manifest.volter?.product?.entry;
418
+ if (typeof path !== 'string') return [];
419
+ entry = readFileSync(join(product.dir, path), 'utf8');
420
+ } catch {
421
+ return [];
422
+ }
423
+ const found: string[] = [];
424
+ for (const [, name] of entry.matchAll(/\bfrom\s+['"]volter:contributions\/([^'"]+)['"]/g)) {
425
+ if (!name || found.includes(name)) continue;
426
+ const dir = locatePackage(product.dir, name);
427
+ if (dir === null) continue;
428
+ let dependency: { volter?: { contributions?: unknown } };
429
+ try {
430
+ dependency = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as typeof dependency;
431
+ } catch {
432
+ continue;
433
+ }
434
+ if (Array.isArray(dependency.volter?.contributions)) found.push(name);
435
+ }
436
+ return found;
437
+ }
438
+
439
+ /** The products this project declares AND resolves, in declaration order. */
440
+ export function declaredProducts(projectRoot: string): ProductIdentity[] {
441
+ const found: ProductIdentity[] = [];
442
+ for (const name of declaredVolterPackages(projectRoot)) {
443
+ const dir = locatePackage(projectRoot, name);
444
+ if (dir === null) continue;
445
+ const product = readProductManifest(dir);
446
+ if (product !== null) found.push(product);
447
+ }
448
+ return found;
449
+ }
450
+
451
+ /**
452
+ * THE product this project opens in, or a throw naming what is wrong.
453
+ *
454
+ * The refusals are the whole point: a project with none and a project with two
455
+ * are both states a person can be in, and neither has an answer this code may
456
+ * invent.
457
+ */
458
+ export function resolveProductForProject(projectRoot: string): ProductIdentity {
459
+ const products = declaredProducts(projectRoot);
460
+ if (products.length === 1) return products[0] as ProductIdentity;
461
+ if (products.length === 0)
462
+ throw new Error(
463
+ `${projectRoot} declares no editor product, so there is no editor to open it in.\n` +
464
+ 'The installed product supplies the editor,\n' +
465
+ 'and which one runs is what the project installed, never a flag.\n' +
466
+ 'For THIS folder, install the one you are building with:\n' +
467
+ `${PRODUCT_INSTALL_LINES.join('\n')}\n` +
468
+ "then run that product's `edit` command again. For a NEW project, the product creates it:\n" +
469
+ `${PRODUCT_CREATE_LINES.join('\n')}`,
470
+ );
471
+ throw new Error(
472
+ `${projectRoot} declares ${products.length} editor products — ` +
473
+ `${products.map((product) => product.name).join(' and ')}.\n` +
474
+ 'One page runs one product, and nothing here may choose between them. Remove the one you\n' +
475
+ 'are not building with:\n' +
476
+ products.map((product) => ` npm uninstall ${product.name}`).join('\n'),
477
+ );
478
+ }