@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.
- package/LICENSE +202 -0
- package/NOTICE +20 -0
- package/README.md +38 -3
- package/package.json +510 -4
- package/src/account.ts +210 -0
- package/src/chrome.ts +88 -0
- package/src/client.ts +1646 -0
- package/src/commands.ts +66 -0
- package/src/contributions.ts +619 -0
- package/src/css-numeric-style.ts +97 -0
- package/src/document-probe.ts +282 -0
- package/src/editor-view.ts +225 -0
- package/src/extension.ts +40 -0
- package/src/generations.ts +178 -0
- package/src/host.ts +1157 -0
- package/src/http-transport.browser.ts +14 -0
- package/src/http-transport.node.ts +19 -0
- package/src/index.ts +131 -0
- package/src/kit/CapabilityCoverageSection.tsx +185 -0
- package/src/kit/account-client.ts +333 -0
- package/src/kit/action-registry.ts +317 -0
- package/src/kit/active-product.ts +76 -0
- package/src/kit/active-project.ts +155 -0
- package/src/kit/adapter-editor-config.ts +25 -0
- package/src/kit/adapter-module.ts +7 -0
- package/src/kit/adapter-observation.ts +49 -0
- package/src/kit/animation/animation-clock.ts +479 -0
- package/src/kit/animation/stage-transport.ts +385 -0
- package/src/kit/api/assets.ts +365 -0
- package/src/kit/api/project-open.ts +355 -0
- package/src/kit/api/project-source.ts +180 -0
- package/src/kit/api/project-state.ts +110 -0
- package/src/kit/api/relay.ts +270 -0
- package/src/kit/api/themes.ts +45 -0
- package/src/kit/api-asset-library-wire.ts +45 -0
- package/src/kit/api-base.ts +10 -0
- package/src/kit/api-build.ts +99 -0
- package/src/kit/api-git-wire.ts +56 -0
- package/src/kit/api-logs.ts +92 -0
- package/src/kit/api-project-identity.ts +74 -0
- package/src/kit/api-settings.ts +36 -0
- package/src/kit/api-worktrees.ts +205 -0
- package/src/kit/asset-capabilities.ts +344 -0
- package/src/kit/asset-compare-core.ts +171 -0
- package/src/kit/asset-editor-context.tsx +101 -0
- package/src/kit/asset-events.ts +96 -0
- package/src/kit/asset-inspector-actions.ts +87 -0
- package/src/kit/asset-selection-viewer-registry.ts +113 -0
- package/src/kit/asset-selection.ts +146 -0
- package/src/kit/asset-thumbnails.ts +25 -0
- package/src/kit/asset-viewers.ts +115 -0
- package/src/kit/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/kit/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/kit/asset-workflow/asset-ledger.ts +156 -0
- package/src/kit/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/kit/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/kit/asset-workflow/asset-types.ts +142 -0
- package/src/kit/asset-workflow/audio-preview-player.ts +193 -0
- package/src/kit/asset-workflow/audio-waveform.ts +22 -0
- package/src/kit/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/kit/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/kit/asset-workflow/image-view-scale.ts +31 -0
- package/src/kit/asset-workflow/import-contract.ts +124 -0
- package/src/kit/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/kit/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/kit/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/kit/asset-workflow/project-asset-commands.ts +20 -0
- package/src/kit/asset-workflow/project-content.ts +288 -0
- package/src/kit/asset-workflow/project-source-index.ts +545 -0
- package/src/kit/asset-workflow/thumbnail-system.ts +256 -0
- package/src/kit/authoring/active-adapter.ts +200 -0
- package/src/kit/authoring/active-systems.ts +422 -0
- package/src/kit/authoring/adapter-key.ts +18 -0
- package/src/kit/authoring/authoring-asset-url.ts +27 -0
- package/src/kit/authoring/bootstrap-state.ts +49 -0
- package/src/kit/authoring/boundary-authoring-adapter.ts +189 -0
- package/src/kit/authoring/canvas-scene-guides.ts +84 -0
- package/src/kit/authoring/composite-authoring-adapter.ts +2109 -0
- package/src/kit/authoring/consumer-actions.ts +531 -0
- package/src/kit/authoring/design-time-layers.ts +852 -0
- package/src/kit/authoring/design-time-mount-registry.ts +244 -0
- package/src/kit/authoring/edit-mode-authoring.ts +637 -0
- package/src/kit/authoring/empty-project-authoring.ts +22 -0
- package/src/kit/authoring/instance-source-menu.ts +135 -0
- package/src/kit/authoring/layered-pick.ts +185 -0
- package/src/kit/authoring/mounted-root-subjects.ts +146 -0
- package/src/kit/authoring/no-authoring-adapter.ts +59 -0
- package/src/kit/authoring/object3d-document-persistence.ts +122 -0
- package/src/kit/authoring/panel-authoring.ts +121 -0
- package/src/kit/authoring/project-authoring-session.ts +105 -0
- package/src/kit/authoring/provenance.ts +99 -0
- package/src/kit/authoring/react-canvas-navigation.ts +259 -0
- package/src/kit/authoring/react-design-canvas-style.ts +20 -0
- package/src/kit/authoring/react-story-board.ts +917 -0
- package/src/kit/authoring/selection-scope.ts +195 -0
- package/src/kit/authoring/shell-document-ops.ts +169 -0
- package/src/kit/authoring/story-board-chrome-fit.ts +107 -0
- package/src/kit/authoring/story-board-presentation.ts +111 -0
- package/src/kit/authoring/three-root.ts +67 -0
- package/src/kit/authoring/viewport-tool-context.ts +73 -0
- package/src/kit/authoring/viewport-tool-owner.ts +38 -0
- package/src/kit/authoring/world-session-state.ts +101 -0
- package/src/kit/authoring-seam-evidence.ts +300 -0
- package/src/kit/availability-tick.ts +66 -0
- package/src/kit/bitmap-label.ts +120 -0
- package/src/kit/boot-routing.ts +392 -0
- package/src/kit/breakpoint-state.ts +43 -0
- package/src/kit/build-identity.ts +16 -0
- package/src/kit/bytes-codec.ts +62 -0
- package/src/kit/cancellation-reason.ts +58 -0
- package/src/kit/canvas-frames.ts +88 -0
- package/src/kit/capture-camera-pose.ts +77 -0
- package/src/kit/capture-size.ts +88 -0
- package/src/kit/chrome-registry.ts +159 -0
- package/src/kit/chrome-slot-registry.ts +91 -0
- package/src/kit/collaboration-client.ts +264 -0
- package/src/kit/collaboration-presence.ts +41 -0
- package/src/kit/command-dispatch.ts +19 -0
- package/src/kit/command-listener.ts +2182 -0
- package/src/kit/command-registry.ts +71 -0
- package/src/kit/component-board-registry.ts +205 -0
- package/src/kit/component-states-registry.ts +199 -0
- package/src/kit/components/AlignToolbar.tsx +204 -0
- package/src/kit/components/ApplicationMenus.tsx +372 -0
- package/src/kit/components/AssetEditorShell.tsx +216 -0
- package/src/kit/components/AssetInspectorToolSection.tsx +124 -0
- package/src/kit/components/BoardRulers.tsx +354 -0
- package/src/kit/components/CanvasAddNodeDialogs.tsx +529 -0
- package/src/kit/components/CanvasSceneViewport.tsx +1195 -0
- package/src/kit/components/ChromeSlot.tsx +20 -0
- package/src/kit/components/CodeView.tsx +470 -0
- package/src/kit/components/CompactInspectorShell.tsx +39 -0
- package/src/kit/components/ConsolePanel.tsx +273 -0
- package/src/kit/components/GameplaySessionTimeline.tsx +295 -0
- package/src/kit/components/InspectionProjection.tsx +932 -0
- package/src/kit/components/Inspector.tsx +270 -0
- package/src/kit/components/InspectorCanvasPreview.tsx +35 -0
- package/src/kit/components/InspectorFieldsSection.tsx +290 -0
- package/src/kit/components/InspectorStoriesSection.tsx +92 -0
- package/src/kit/components/InspectorToolSection.tsx +96 -0
- package/src/kit/components/InspectorTransformSection.tsx +245 -0
- package/src/kit/components/LightExplorerPanel.tsx +433 -0
- package/src/kit/components/MediaProperties.tsx +145 -0
- package/src/kit/components/ProjectHeader.tsx +328 -0
- package/src/kit/components/ReactCanvasControls.tsx +358 -0
- package/src/kit/components/RootSelectionOverlay.tsx +3688 -0
- package/src/kit/components/RootTextEditor.tsx +79 -0
- package/src/kit/components/SaveStatus.tsx +70 -0
- package/src/kit/components/SurfaceCrashBoundary.tsx +105 -0
- package/src/kit/components/SurfaceStateOverlay.tsx +24 -0
- package/src/kit/components/ToolContributionSurfaces.tsx +49 -0
- package/src/kit/components/ToolHost.tsx +380 -0
- package/src/kit/components/Toolbar.tsx +811 -0
- package/src/kit/components/TransientHint.tsx +44 -0
- package/src/kit/components/VersionControlSection.tsx +470 -0
- package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
- package/src/kit/components/VolterLogo.tsx +18 -0
- package/src/kit/components/WorktreeSwitcher.tsx +712 -0
- package/src/kit/components/account-documents.tsx +1162 -0
- package/src/kit/components/asset-documents.tsx +794 -0
- package/src/kit/components/asset-editor-persistence.ts +216 -0
- package/src/kit/components/asset-selection-section.tsx +545 -0
- package/src/kit/components/asset-thumbnails.tsx +307 -0
- package/src/kit/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/kit/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/kit/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/kit/components/asset-viewers/JsonAssetDocument.tsx +98 -0
- package/src/kit/components/asset-viewers/OnlineAssetDetail.tsx +426 -0
- package/src/kit/components/asset-viewers/SourceAssetViewer.tsx +356 -0
- package/src/kit/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/kit/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/kit/components/asset-viewers/shader-source.ts +144 -0
- package/src/kit/components/board-guides.ts +150 -0
- package/src/kit/components/canvas-scene-hotkeys.ts +37 -0
- package/src/kit/components/canvas-temporary-pivot.ts +34 -0
- package/src/kit/components/core-utilities.tsx +94 -0
- package/src/kit/components/inspector-preview-section.tsx +223 -0
- package/src/kit/components/inspector-revert-label.ts +20 -0
- package/src/kit/components/inspector-selection.ts +42 -0
- package/src/kit/components/inspector-stories-gating.ts +171 -0
- package/src/kit/components/inspector-transform-subject.ts +11 -0
- package/src/kit/components/inspector-transform.ts +88 -0
- package/src/kit/components/kind-documents.tsx +544 -0
- package/src/kit/components/primitives/DraftColorInput.tsx +74 -0
- package/src/kit/components/project-tool-documents.tsx +402 -0
- package/src/kit/components/scene-documents.tsx +221 -0
- package/src/kit/components/status-contributions.tsx +407 -0
- package/src/kit/components/tool-documents.tsx +302 -0
- package/src/kit/components/tool-schema-form.tsx +262 -0
- package/src/kit/components/use-after-paint.ts +41 -0
- package/src/kit/components/use-project-image-assets.ts +86 -0
- package/src/kit/components/workspace-history.ts +32 -0
- package/src/kit/components/world-documents.tsx +570 -0
- package/src/kit/components/world-overlay-gestures.ts +1939 -0
- package/src/kit/composite-screenshot.ts +2238 -0
- package/src/kit/content-entry-source-registry.ts +184 -0
- package/src/kit/contribution-surfaces.ts +48 -0
- package/src/kit/coverage/canvas-reveal.ts +192 -0
- package/src/kit/coverage/design-time-surfaces.ts +101 -0
- package/src/kit/coverage/ontology-invariants.ts +466 -0
- package/src/kit/coverage/session-vitals.ts +503 -0
- package/src/kit/crash-null-boundary.ts +36 -0
- package/src/kit/creation-site-edit.ts +1491 -0
- package/src/kit/creation-site-registry.ts +160 -0
- package/src/kit/delegate-harness-registry.ts +134 -0
- package/src/kit/document-areas.ts +70 -0
- package/src/kit/document-context-registry.ts +193 -0
- package/src/kit/document-open-registry.ts +200 -0
- package/src/kit/document-play-extension.ts +221 -0
- package/src/kit/document-preview-source.ts +20 -0
- package/src/kit/document-renderer-session.ts +138 -0
- package/src/kit/document-stage-sessions.ts +26 -0
- package/src/kit/document-viewports.ts +120 -0
- package/src/kit/editor-api.ts +46 -0
- package/src/kit/editor-chrome-capture.ts +136 -0
- package/src/kit/editor-commands.ts +176 -0
- package/src/kit/editor-console.ts +580 -0
- package/src/kit/editor-current-view.ts +56 -0
- package/src/kit/editor-document-probe.ts +1166 -0
- package/src/kit/editor-git-client.ts +115 -0
- package/src/kit/editor-hotkeys.ts +728 -0
- package/src/kit/editor-lease-view.ts +39 -0
- package/src/kit/editor-lease.ts +415 -0
- package/src/kit/editor-mode.ts +19 -0
- package/src/kit/editor-notifications.ts +140 -0
- package/src/kit/editor-presence.ts +563 -0
- package/src/kit/editor-presentation-activity.ts +58 -0
- package/src/kit/editor-presentation-notice.ts +42 -0
- package/src/kit/editor-runtime.tsx +147 -0
- package/src/kit/editor-server-response.ts +86 -0
- package/src/kit/editor-session-attribution.ts +85 -0
- package/src/kit/editor-session-mode.ts +54 -0
- package/src/kit/editor-state-facets.ts +74 -0
- package/src/kit/editor-view-presentation.ts +777 -0
- package/src/kit/environment-images.ts +58 -0
- package/src/kit/eyedropper-session.ts +60 -0
- package/src/kit/files/file-provider.ts +62 -0
- package/src/kit/files/project-files.ts +270 -0
- package/src/kit/finders/index.ts +137 -0
- package/src/kit/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/kit/frame/frame-parts.ts +30 -0
- package/src/kit/framed-document-capture.ts +34 -0
- package/src/kit/game-globals-prelude.ts +143 -0
- package/src/kit/game-surface-defaults.ts +33 -0
- package/src/kit/gameplay-dom-recording.ts +318 -0
- package/src/kit/gameplay-export-state.ts +14 -0
- package/src/kit/gameplay-replay.ts +417 -0
- package/src/kit/gameplay-session-time.ts +9 -0
- package/src/kit/gameplay-sessions.ts +204 -0
- package/src/kit/hierarchy-component-marks.ts +298 -0
- package/src/kit/hierarchy-internals.ts +197 -0
- package/src/kit/hierarchy-kind-icon.ts +217 -0
- package/src/kit/hierarchy-menu-registry.ts +67 -0
- package/src/kit/hierarchy-node-rows.ts +307 -0
- package/src/kit/hierarchy-panel-view.ts +280 -0
- package/src/kit/hierarchy-projection.ts +76 -0
- package/src/kit/hierarchy-row-media.ts +45 -0
- package/src/kit/hierarchy-row-model.ts +308 -0
- package/src/kit/hierarchy-rows.ts +11 -0
- package/src/kit/hierarchy-walk.ts +86 -0
- package/src/kit/history/editor-session.ts +25 -0
- package/src/kit/history/history-commands.ts +147 -0
- package/src/kit/history/history-delegate.ts +187 -0
- package/src/kit/history/history-limit-notices.ts +43 -0
- package/src/kit/history/history-service.ts +1189 -0
- package/src/kit/history/persistence-coordinator.ts +35 -0
- package/src/kit/history/project-file-history.ts +386 -0
- package/src/kit/history/project-root-history-backends.ts +139 -0
- package/src/kit/history/resource-registry.ts +209 -0
- package/src/kit/history/snapshot-store.ts +103 -0
- package/src/kit/history/source-history-backend.ts +546 -0
- package/src/kit/history-types.ts +124 -0
- package/src/kit/hmr-registration-group.ts +67 -0
- package/src/kit/hmr-stable-react-context.ts +23 -0
- package/src/kit/hotkeys.ts +190 -0
- package/src/kit/inference-diagnostics.ts +69 -0
- package/src/kit/initial-project.ts +80 -0
- package/src/kit/inspection/active-subject.ts +571 -0
- package/src/kit/inspection/active-surface.ts +142 -0
- package/src/kit/inspection/compose-subject.ts +1055 -0
- package/src/kit/inspection/compose.ts +7 -0
- package/src/kit/inspection/display.ts +171 -0
- package/src/kit/inspection/document-subject.ts +109 -0
- package/src/kit/inspection/game-subject.ts +85 -0
- package/src/kit/inspection/null-subject.ts +119 -0
- package/src/kit/inspection/serialize.ts +357 -0
- package/src/kit/inspection/use-active-inspection.ts +180 -0
- package/src/kit/inspection-model.ts +542 -0
- package/src/kit/inspection-node-media.ts +58 -0
- package/src/kit/inspector-presentation.ts +203 -0
- package/src/kit/inspector-property-grouping.ts +64 -0
- package/src/kit/inspector-section-registry.ts +221 -0
- package/src/kit/instance-source-actions.ts +163 -0
- package/src/kit/js-heap.ts +71 -0
- package/src/kit/key-actions.ts +91 -0
- package/src/kit/keymap-presets.ts +428 -0
- package/src/kit/layout-policy.ts +31 -0
- package/src/kit/light-explorer-model.ts +134 -0
- package/src/kit/live-canvas-frame.ts +55 -0
- package/src/kit/live-document.ts +296 -0
- package/src/kit/live-gesture-lock.ts +50 -0
- package/src/kit/live-seam-evidence.ts +11 -0
- package/src/kit/live-session-registry.ts +220 -0
- package/src/kit/live-transition.ts +391 -0
- package/src/kit/manifest-project.ts +107 -0
- package/src/kit/module-fetch-diagnosis.ts +192 -0
- package/src/kit/mount-failure-report.ts +154 -0
- package/src/kit/native-selection-style.ts +497 -0
- package/src/kit/object3d-document-write-policy.ts +137 -0
- package/src/kit/packaged-runtime.ts +108 -0
- package/src/kit/palettes/maya.palette.json +57 -0
- package/src/kit/palettes/substance.palette.json +57 -0
- package/src/kit/performance-profiler.ts +367 -0
- package/src/kit/performance-sources.ts +69 -0
- package/src/kit/photograph-notice.ts +141 -0
- package/src/kit/play-boot-phase.ts +166 -0
- package/src/kit/play-camera-flight.ts +35 -0
- package/src/kit/png-encode.worker.ts +26 -0
- package/src/kit/presentation-surface.ts +248 -0
- package/src/kit/product-command.ts +90 -0
- package/src/kit/project-adapter.ts +1140 -0
- package/src/kit/project-asset-refresh.ts +23 -0
- package/src/kit/project-asset-roots.ts +68 -0
- package/src/kit/project-local-state.ts +151 -0
- package/src/kit/project-manager.ts +243 -0
- package/src/kit/project-module-changes.ts +201 -0
- package/src/kit/project-module-split.ts +270 -0
- package/src/kit/project-play-layers.ts +25 -0
- package/src/kit/project-provenance.ts +115 -0
- package/src/kit/project-ready.ts +42 -0
- package/src/kit/project-shape.ts +68 -0
- package/src/kit/project-tools.ts +107 -0
- package/src/kit/projection-types.ts +44 -0
- package/src/kit/readiness.ts +113 -0
- package/src/kit/renderer-resource-counts.ts +27 -0
- package/src/kit/reported-play-state.ts +90 -0
- package/src/kit/resolve-contributed-command.ts +14 -0
- package/src/kit/resolve-relative-specifier.ts +33 -0
- package/src/kit/retained-document-states.ts +91 -0
- package/src/kit/scene-document-plan.ts +320 -0
- package/src/kit/scene-live-open.ts +210 -0
- package/src/kit/scoped-game-css.ts +152 -0
- package/src/kit/served-url.ts +5 -0
- package/src/kit/session-close.ts +17 -0
- package/src/kit/session-tombstone.ts +127 -0
- package/src/kit/settings/settings-provider.ts +82 -0
- package/src/kit/settings-store.ts +348 -0
- package/src/kit/shell-document-state.ts +27 -0
- package/src/kit/shell-store-door.ts +45 -0
- package/src/kit/shell-store.ts +722 -0
- package/src/kit/source-conflict.ts +122 -0
- package/src/kit/stage-context.ts +377 -0
- package/src/kit/stage-invalidation.ts +25 -0
- package/src/kit/stage-store-registry.ts +69 -0
- package/src/kit/startup-failure.ts +80 -0
- package/src/kit/state-report-deferral.ts +73 -0
- package/src/kit/storage/host-files-storage.ts +97 -0
- package/src/kit/storage/http-storage.ts +174 -0
- package/src/kit/storage/index.ts +75 -0
- package/src/kit/storage/mem-storage.ts +158 -0
- package/src/kit/storage/path-lock.ts +44 -0
- package/src/kit/storage/paths.ts +26 -0
- package/src/kit/storage-types.ts +127 -0
- package/src/kit/stories/StoryPreviewMount.tsx +306 -0
- package/src/kit/stories/compose-project-stories.ts +255 -0
- package/src/kit/stories/prefabs-finder.ts +54 -0
- package/src/kit/stories/prefabs-from-stories.ts +182 -0
- package/src/kit/stories/project-story-regions.ts +24 -0
- package/src/kit/stories/story-capture.ts +579 -0
- package/src/kit/stories/story-declared-medium.ts +126 -0
- package/src/kit/stories/story-discovery.ts +176 -0
- package/src/kit/stories/story-dom-runtime.ts +78 -0
- package/src/kit/stories/story-grouping.ts +111 -0
- package/src/kit/stories/story-mount-turn.ts +27 -0
- package/src/kit/stories/story-presentation.ts +215 -0
- package/src/kit/stories/story-preview-component.ts +7 -0
- package/src/kit/stories/story-registry.ts +530 -0
- package/src/kit/stories-scope.ts +35 -0
- package/src/kit/story-document-openers.ts +36 -0
- package/src/kit/story-thumbnails.ts +47 -0
- package/src/kit/surface-keyboard.ts +101 -0
- package/src/kit/surface-state.ts +135 -0
- package/src/kit/system-seam-evidence.ts +72 -0
- package/src/kit/tab-census.ts +202 -0
- package/src/kit/tab-lifecycle-client.ts +227 -0
- package/src/kit/theme-library.ts +897 -0
- package/src/kit/theme-preference.ts +429 -0
- package/src/kit/three-viewport-presentation.ts +23 -0
- package/src/kit/tool-contribution-play.ts +74 -0
- package/src/kit/tool-loader.ts +1918 -0
- package/src/kit/transform-mode-request.ts +66 -0
- package/src/kit/transient-hint.ts +78 -0
- package/src/kit/transport-strip.tsx +174 -0
- package/src/kit/ui-source/adapter-region-includes.ts +238 -0
- package/src/kit/ui-source/file-region-resolver.ts +302 -0
- package/src/kit/ui-source/inspect.ts +775 -0
- package/src/kit/ui-source/source-write-backend.ts +605 -0
- package/src/kit/ui-source/tier-source-write-backend.ts +279 -0
- package/src/kit/user-local-state.ts +105 -0
- package/src/kit/viewport-activation-timings.ts +840 -0
- package/src/kit/viewport-editor-controls.ts +22 -0
- package/src/kit/viewport-presentation.ts +668 -0
- package/src/kit/viewport-surface-status.tsx +55 -0
- package/src/kit/wait-until.ts +37 -0
- package/src/kit/worker-call-metrics.ts +166 -0
- package/src/kit/workspace-areas.ts +191 -0
- package/src/kit/workspace-aux-commands.ts +11 -0
- package/src/kit/workspace-available-documents.ts +142 -0
- package/src/kit/workspace-core-utilities.ts +31 -0
- package/src/kit/workspace-document-ids.ts +59 -0
- package/src/kit/workspace-document-registry.ts +624 -0
- package/src/kit/workspace-document-restore.ts +146 -0
- package/src/kit/workspace-host-commands.ts +141 -0
- package/src/kit/workspace-persistence-gate.ts +40 -0
- package/src/kit/workspace-play-utilities.ts +44 -0
- package/src/kit/workspace-presets.ts +446 -0
- package/src/kit/workspace-regions.ts +276 -0
- package/src/kit/workspace-static-panels.ts +73 -0
- package/src/kit/workspace-status-registry.ts +121 -0
- package/src/kit/workspace-storage.ts +35 -0
- package/src/kit/workspace-style.ts +226 -0
- package/src/kit/workspace-utility-commands.ts +74 -0
- package/src/kit/workspace-utility-registry.ts +263 -0
- package/src/kit/world-adoption-event.ts +23 -0
- package/src/kit/world-adoption.ts +115 -0
- package/src/kit/world-canvas-viewport-state.ts +35 -0
- package/src/kit/world-document-routing.ts +104 -0
- package/src/kit/world-pan-state.ts +198 -0
- package/src/kit/write-pipe.ts +173 -0
- package/src/layout-arrangements.ts +5 -0
- package/src/layouts.tsx +108 -0
- package/src/looks.ts +16 -0
- package/src/project/output-roots.ts +73 -0
- package/src/project/tab-census.ts +155 -0
- package/src/project-tool-catalog.ts +104 -0
- package/src/selection.tsx +107 -0
- package/src/services.ts +18 -0
- package/src/session/build-report.ts +22 -0
- package/src/session/collaboration-types.ts +262 -0
- package/src/session/command-table.ts +327 -0
- package/src/session/discovery.ts +100 -0
- package/src/session/editor-brand.ts +48 -0
- package/src/session/editor-compatibility.ts +317 -0
- package/src/session/editor-control-lifecycle.ts +68 -0
- package/src/session/editor-control-protocol.ts +5 -0
- package/src/session/entrypoint-selection-readers.ts +66 -0
- package/src/session/entrypoint-selection-source.ts +120 -0
- package/src/session/game-css-scope.ts +30 -0
- package/src/session/hosted-attachment.ts +225 -0
- package/src/session/limited-view.ts +82 -0
- package/src/session/product-create.ts +24 -0
- package/src/session/product-locator.ts +478 -0
- package/src/session/project-module-url.ts +242 -0
- package/src/session/project-serving.ts +164 -0
- package/src/session/project-upgrade.ts +403 -0
- package/src/session/registry-format.ts +210 -0
- package/src/session/relative-path-guard.ts +56 -0
- package/src/session/scoped-game-css.ts +461 -0
- package/src/session/source-glob.ts +15 -0
- package/src/session/tool-contribution-convention.ts +123 -0
- package/src/session/workbench-locator.ts +712 -0
- package/src/session.ts +41 -0
- package/src/share.ts +160 -0
- package/src/source-analysis.ts +28 -0
- package/src/source-authoring.ts +439 -0
- package/src/tools/errors.ts +91 -0
- package/src/tools/provider-execution.ts +70 -0
- package/src/tools/registry.ts +341 -0
- package/src/tools/types.ts +159 -0
- package/src/transport.ts +100 -0
- package/src/types.ts +1693 -0
- package/src/views.ts +164 -0
- package/src/widgets/design-system.ts +93 -0
- package/src/widgets/editor-appearance.ts +151 -0
- package/src/widgets/editor-material.ts +83 -0
- package/src/widgets/icon-set-registry.ts +105 -0
- package/src/widgets/index.ts +71 -0
- package/src/widgets/inspector-widgets/AlignmentGrid.tsx +182 -0
- package/src/widgets/inspector-widgets/AssetSlotPicker.tsx +123 -0
- package/src/widgets/inspector-widgets/BorderEditor.tsx +309 -0
- package/src/widgets/inspector-widgets/ColorPicker.tsx +549 -0
- package/src/widgets/inspector-widgets/CurveEditor.tsx +359 -0
- package/src/widgets/inspector-widgets/FilterEditor.tsx +108 -0
- package/src/widgets/inspector-widgets/FontPicker.tsx +191 -0
- package/src/widgets/inspector-widgets/GradientEditor.tsx +623 -0
- package/src/widgets/inspector-widgets/ScrubbableInput.tsx +180 -0
- package/src/widgets/inspector-widgets/ShadowEditor.tsx +319 -0
- package/src/widgets/inspector-widgets/color-utils.ts +201 -0
- package/src/widgets/inspector-widgets/curve-utils.ts +212 -0
- package/src/widgets/inspector-widgets/index.ts +25 -0
- package/src/widgets/inspector-widgets/shared.tsx +140 -0
- package/src/widgets/interactive-edit-scope.ts +33 -0
- package/src/widgets/patterns/Dialog.tsx +140 -0
- package/src/widgets/patterns/Fields.tsx +44 -0
- package/src/widgets/patterns/List.tsx +25 -0
- package/src/widgets/patterns/StateSurface.tsx +40 -0
- package/src/widgets/patterns/Surfaces.tsx +122 -0
- package/src/widgets/patterns/Tabs.tsx +80 -0
- package/src/widgets/patterns/Toolbar.tsx +72 -0
- package/src/widgets/patterns/Tree.tsx +72 -0
- package/src/widgets/primitives/AnchoredMenu.tsx +260 -0
- package/src/widgets/primitives/Button.tsx +62 -0
- package/src/widgets/primitives/ColorInput.tsx +78 -0
- package/src/widgets/primitives/DraftTextInput.tsx +63 -0
- package/src/widgets/primitives/EditorIcon.tsx +157 -0
- package/src/widgets/primitives/FormControls.tsx +88 -0
- package/src/widgets/primitives/HoverPreview.tsx +96 -0
- package/src/widgets/primitives/JsonInput.tsx +113 -0
- package/src/widgets/primitives/Layout.tsx +100 -0
- package/src/widgets/primitives/Menu.tsx +161 -0
- package/src/widgets/primitives/NumberInput.tsx +169 -0
- package/src/widgets/primitives/Panel.tsx +80 -0
- package/src/widgets/primitives/SectionHeader.tsx +77 -0
- package/src/widgets/primitives/Text.tsx +54 -0
- package/src/widgets/primitives/ThemeRootPortal.tsx +52 -0
- package/src/widgets/primitives/Tooltip.tsx +204 -0
- package/src/widgets/primitives/Vec3Input.tsx +70 -0
- package/src/widgets/primitives/banner-tones.ts +32 -0
- package/src/widgets/primitives/clamp-to-viewport.ts +44 -0
- package/src/widgets/primitives/editor-icons.ts +254 -0
- package/src/widgets/primitives/panel-header-styles.ts +42 -0
- package/src/widgets/theme.ts +2841 -0
- package/src/widgets/z-index.ts +25 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace STYLE BUNDLES (Glass-UI spike, Unit 3, "New named style using
|
|
3
|
+
* existing axes" row).
|
|
4
|
+
*
|
|
5
|
+
* Named one-shot presets over PALETTE + MATERIAL + ICONS: how things are DRAWN, and nothing
|
|
6
|
+
* else (ARCHITECTURE.md rule 7). The axes stay independently selectable; choosing a named style
|
|
7
|
+
* intentionally restores its canonical complete appearance. In particular, Classic must restore
|
|
8
|
+
* the original Graphite contract rather than inheriting a Glass palette. Which chrome regions
|
|
9
|
+
* exist is function — a workspace's (`workspace-regions.ts`), never a style's.
|
|
10
|
+
*
|
|
11
|
+
* Bundles are ONE-SHOT PRESETS, not a fifth stored axis: applying a bundle
|
|
12
|
+
* just calls the four existing axis setters, and this module keeps no store
|
|
13
|
+
* or persistence of its own. "Which bundle is active" is always DERIVED
|
|
14
|
+
* from their current values (`activeWorkspaceStyleId`) and can never
|
|
15
|
+
* disagree with them — e.g. after a user independently changes just the
|
|
16
|
+
* material, the derived id correctly falls back to `null` (a "custom" mix)
|
|
17
|
+
* rather than going stale.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { StyleContribution } from '@volter/sdk/looks';
|
|
21
|
+
import type { EditorMaterialId, EditorPalette } from '@volter/sdk/widgets';
|
|
22
|
+
import {
|
|
23
|
+
DEFAULT_ICON_SET_ID,
|
|
24
|
+
registerContributedIconSet,
|
|
25
|
+
registerContributedMaterial,
|
|
26
|
+
} from '@volter/sdk/widgets';
|
|
27
|
+
import { activeProduct, subscribeActiveProduct } from './active-product';
|
|
28
|
+
import { registerContributedPalette } from './theme-library';
|
|
29
|
+
import {
|
|
30
|
+
editorIconSetSnapshot,
|
|
31
|
+
editorMaterialSnapshot,
|
|
32
|
+
editorPaletteSnapshot,
|
|
33
|
+
setDefaultEditorAppearance,
|
|
34
|
+
setEditorIconSetPreference,
|
|
35
|
+
setEditorMaterialPreference,
|
|
36
|
+
setEditorPalettePreference,
|
|
37
|
+
} from './theme-preference';
|
|
38
|
+
|
|
39
|
+
export interface WorkspaceStyleBundle {
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly title: string;
|
|
42
|
+
readonly paletteId: EditorPalette['id'];
|
|
43
|
+
readonly materialId: EditorMaterialId;
|
|
44
|
+
/** `icon-set-registry.ts`; `default` is the editor's own glyphs. */
|
|
45
|
+
readonly iconSetId: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Frozen built-in list — the switch surface (command palette / View menu)
|
|
49
|
+
* enumerates this directly. */
|
|
50
|
+
const BUILT_IN_STYLES: readonly WorkspaceStyleBundle[] = Object.freeze([
|
|
51
|
+
{
|
|
52
|
+
id: 'classic',
|
|
53
|
+
title: 'Classic',
|
|
54
|
+
paletteId: 'graphite-dark',
|
|
55
|
+
materialId: 'classic',
|
|
56
|
+
iconSetId: DEFAULT_ICON_SET_ID,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'glass',
|
|
60
|
+
title: 'Glass',
|
|
61
|
+
paletteId: 'graphite-neutral',
|
|
62
|
+
materialId: 'glass',
|
|
63
|
+
iconSetId: DEFAULT_ICON_SET_ID,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'maya',
|
|
67
|
+
title: 'Maya',
|
|
68
|
+
paletteId: 'maya',
|
|
69
|
+
materialId: 'classic',
|
|
70
|
+
iconSetId: DEFAULT_ICON_SET_ID,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'substance',
|
|
74
|
+
title: 'Substance',
|
|
75
|
+
paletteId: 'substance',
|
|
76
|
+
materialId: 'classic',
|
|
77
|
+
iconSetId: DEFAULT_ICON_SET_ID,
|
|
78
|
+
},
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
interface ContributedStyle {
|
|
82
|
+
readonly bundle: WorkspaceStyleBundle;
|
|
83
|
+
readonly unregisterPalette: (() => void) | null;
|
|
84
|
+
readonly unregisterMaterial: (() => void) | null;
|
|
85
|
+
readonly unregisterIconSet: (() => void) | null;
|
|
86
|
+
}
|
|
87
|
+
const contributedStyles = new Map<string, ContributedStyle>();
|
|
88
|
+
let registryVersion = 0;
|
|
89
|
+
const registryListeners = new Set<() => void>();
|
|
90
|
+
|
|
91
|
+
/** Built-ins first, then contributions in registration order — the switch
|
|
92
|
+
* surfaces (View menu, palette) enumerate this. */
|
|
93
|
+
export function workspaceStyles(): readonly WorkspaceStyleBundle[] {
|
|
94
|
+
return [...BUILT_IN_STYLES, ...[...contributedStyles.values()].map((entry) => entry.bundle)];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function workspaceStylesVersion(): number {
|
|
98
|
+
return registryVersion;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function subscribeWorkspaceStyles(listener: () => void): () => void {
|
|
102
|
+
registryListeners.add(listener);
|
|
103
|
+
return () => registryListeners.delete(listener);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Register a package's style bundle (`workspace.style` contribution), with
|
|
108
|
+
* the palette document and the material it carries registered first — the
|
|
109
|
+
* bundle names their ids, and an id must exist before the bundle can be
|
|
110
|
+
* applied. Returns the unregister. A duplicate id throws.
|
|
111
|
+
*/
|
|
112
|
+
export function registerContributedStyle(contribution: StyleContribution): () => void {
|
|
113
|
+
if (
|
|
114
|
+
BUILT_IN_STYLES.some((entry) => entry.id === contribution.id) ||
|
|
115
|
+
contributedStyles.has(contribution.id)
|
|
116
|
+
)
|
|
117
|
+
throw new Error(`registerContributedStyle: style "${contribution.id}" is already registered.`);
|
|
118
|
+
const unregisterPalette =
|
|
119
|
+
contribution.palette === undefined ? null : registerContributedPalette(contribution.palette);
|
|
120
|
+
const unregisterMaterial =
|
|
121
|
+
contribution.material === undefined ? null : registerContributedMaterial(contribution.material);
|
|
122
|
+
const unregisterIconSet =
|
|
123
|
+
contribution.icons === undefined ? null : registerContributedIconSet(contribution.icons);
|
|
124
|
+
const entry: ContributedStyle = {
|
|
125
|
+
bundle: {
|
|
126
|
+
id: contribution.id,
|
|
127
|
+
title: contribution.title,
|
|
128
|
+
paletteId: contribution.paletteId,
|
|
129
|
+
materialId: contribution.materialId,
|
|
130
|
+
iconSetId: contribution.iconSetId ?? contribution.icons?.id ?? DEFAULT_ICON_SET_ID,
|
|
131
|
+
},
|
|
132
|
+
unregisterPalette,
|
|
133
|
+
unregisterMaterial,
|
|
134
|
+
unregisterIconSet,
|
|
135
|
+
};
|
|
136
|
+
contributedStyles.set(contribution.id, entry);
|
|
137
|
+
registryVersion++;
|
|
138
|
+
for (const listener of registryListeners) listener();
|
|
139
|
+
// The product's look is usually one of these (the Blender look ships inside
|
|
140
|
+
// `@volter/editor-blender`), so the id it named only becomes resolvable here.
|
|
141
|
+
publishProductLook();
|
|
142
|
+
return () => {
|
|
143
|
+
if (contributedStyles.get(contribution.id) !== entry) return;
|
|
144
|
+
contributedStyles.delete(contribution.id);
|
|
145
|
+
entry.unregisterPalette?.();
|
|
146
|
+
entry.unregisterMaterial?.();
|
|
147
|
+
entry.unregisterIconSet?.();
|
|
148
|
+
registryVersion++;
|
|
149
|
+
for (const listener of registryListeners) listener();
|
|
150
|
+
publishProductLook();
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* THE PRODUCT'S LOOK, RESOLVED TO ITS AXES — the one thing this module does for
|
|
156
|
+
* a composition rather than for a gesture.
|
|
157
|
+
*
|
|
158
|
+
* A product names a style bundle id (`frame/product.ts`'s `look`); this is the
|
|
159
|
+
* module that knows what a bundle IS, so it resolves the id and pushes the
|
|
160
|
+
* palette/material/icons behind `theme-preference.ts`'s defaults. It runs on
|
|
161
|
+
* every registry change because a product's own look usually arrives as one of
|
|
162
|
+
* its packages' `workspace.style` contributions, which register a moment into
|
|
163
|
+
* the session — the Blender look is the worked case.
|
|
164
|
+
*
|
|
165
|
+
* It applies nothing and persists nothing: a bundle a person CHOOSES goes
|
|
166
|
+
* through {@link applyWorkspaceStyle}, which writes the preference. This is the
|
|
167
|
+
* floor under that.
|
|
168
|
+
*/
|
|
169
|
+
function publishProductLook(): void {
|
|
170
|
+
const declared = activeProduct()?.look;
|
|
171
|
+
if (declared === undefined) {
|
|
172
|
+
setDefaultEditorAppearance(null);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const bundle = workspaceStyles().find((entry) => entry.id === declared);
|
|
176
|
+
if (!bundle) return;
|
|
177
|
+
setDefaultEditorAppearance({
|
|
178
|
+
palette: bundle.paletteId,
|
|
179
|
+
material: bundle.materialId,
|
|
180
|
+
icons: bundle.iconSetId,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
subscribeActiveProduct(publishProductLook);
|
|
185
|
+
publishProductLook();
|
|
186
|
+
|
|
187
|
+
/** Apply the three axes of the named bundle. Unknown ids are a silent no-op —
|
|
188
|
+
* callers (menu/command palette) only ever offer ids from {@link workspaceStyles}. */
|
|
189
|
+
export function applyWorkspaceStyle(id: string): void {
|
|
190
|
+
const bundle = workspaceStyles().find((entry) => entry.id === id);
|
|
191
|
+
if (!bundle) return;
|
|
192
|
+
setEditorPalettePreference(bundle.paletteId);
|
|
193
|
+
setEditorMaterialPreference(bundle.materialId);
|
|
194
|
+
setEditorIconSetPreference(bundle.iconSetId);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Each axis on which the chrome's current value differs from the bundle `id`'s, as
|
|
198
|
+
* `axis: wearing <value>, bundle <value>` — what a caller told "custom mix" needs to act on. */
|
|
199
|
+
export function workspaceStyleDifferences(id: string): string[] {
|
|
200
|
+
const bundle = workspaceStyles().find((entry) => entry.id === id);
|
|
201
|
+
if (!bundle) return [`no style bundle "${id}"`];
|
|
202
|
+
const rows: Array<[string, string, string]> = [
|
|
203
|
+
['palette', editorPaletteSnapshot(), bundle.paletteId],
|
|
204
|
+
['material', editorMaterialSnapshot(), bundle.materialId],
|
|
205
|
+
['icons', editorIconSetSnapshot(), bundle.iconSetId],
|
|
206
|
+
];
|
|
207
|
+
return rows
|
|
208
|
+
.filter(([, wearing, wanted]) => wearing !== wanted)
|
|
209
|
+
.map(([axis, wearing, wanted]) => `${axis}: wearing ${wearing}, bundle ${wanted}`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** The bundle id whose palette, material and icon set all match the
|
|
213
|
+
* current axis values, or `null` if the current combination isn't any
|
|
214
|
+
* registered bundle (a "custom" mix — always derived, never a separate
|
|
215
|
+
* stored state). */
|
|
216
|
+
export function activeWorkspaceStyleId(): string | null {
|
|
217
|
+
const paletteId = editorPaletteSnapshot();
|
|
218
|
+
const materialId = editorMaterialSnapshot();
|
|
219
|
+
const bundle = workspaceStyles().find(
|
|
220
|
+
(entry) =>
|
|
221
|
+
entry.paletteId === paletteId &&
|
|
222
|
+
entry.materialId === materialId &&
|
|
223
|
+
entry.iconSetId === editorIconSetSnapshot()
|
|
224
|
+
);
|
|
225
|
+
return bundle?.id ?? null;
|
|
226
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/** Semantic commands and failure auto-open policy for workspace utilities. */
|
|
2
|
+
|
|
3
|
+
import { getMountFailureReports, subscribeToMountFailures } from '@volter/sdk/kit/mount-failure-report';
|
|
4
|
+
import { editorConsole } from '@volter/sdk/kit/editor-console';
|
|
5
|
+
import type { HistoryService } from '@volter/sdk/kit/history/history-service';
|
|
6
|
+
import { showWorkspaceUtility, toggleWorkspaceUtility } from '@volter/sdk/kit/workspace-host-commands';
|
|
7
|
+
import { activeChromeRegions } from '@volter/sdk/kit/workspace-regions';
|
|
8
|
+
|
|
9
|
+
export const CONSOLE_UTILITY_ID = 'console';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Only actionable failures open a utility automatically.
|
|
13
|
+
*
|
|
14
|
+
* A world that did not mount is the most actionable failure the editor has —
|
|
15
|
+
* the project is showing something that is not the game — and revealing the
|
|
16
|
+
* Console (where every mount route already wrote its full line) is what keeps
|
|
17
|
+
* it LOUD without a second error surface. This replaced a top-of-shell red
|
|
18
|
+
* banner: the reveal, not the banner, is the answer to "the Console is not
|
|
19
|
+
* the default bottom tab". Fires on the empty→failing EDGE only, so a second
|
|
20
|
+
* failing world in the same attempt does not yank the region back.
|
|
21
|
+
*
|
|
22
|
+
* Source persistence failures arrive through the project history that guarded
|
|
23
|
+
* and rolled back the write. Watch its failure EDGE directly: this keeps the
|
|
24
|
+
* Console reveal format-neutral and avoids a second adapter-specific event.
|
|
25
|
+
*
|
|
26
|
+
* A workspace whose regions HIDE the drawer (Blender's modeling workspace has
|
|
27
|
+
* no strip below the viewport) is never yanked open by this policy: the
|
|
28
|
+
* status bar's error count stays the loud surface there, and a person's own
|
|
29
|
+
* gesture (a failure item, View → Console) still reveals it.
|
|
30
|
+
*/
|
|
31
|
+
export function installUtilityAutoOpen(history: HistoryService): () => void {
|
|
32
|
+
let hadMountFailure = getMountFailureReports().length > 0;
|
|
33
|
+
const stopMountFailures = subscribeToMountFailures(() => {
|
|
34
|
+
const failing = getMountFailureReports().length > 0;
|
|
35
|
+
if (failing && !hadMountFailure && activeChromeRegions().drawer !== 'hidden')
|
|
36
|
+
showWorkspaceUtility(CONSOLE_UTILITY_ID);
|
|
37
|
+
hadMountFailure = failing;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
let hadSourceFailure = history.getSnapshot().lastError !== null;
|
|
41
|
+
const stopHistory = history.subscribe(() => {
|
|
42
|
+
const error = history.getSnapshot().lastError;
|
|
43
|
+
const failing = error !== null;
|
|
44
|
+
if (failing && !hadSourceFailure) {
|
|
45
|
+
// The one place every rolled-back write is named for the DOOR: the
|
|
46
|
+
// screen narrates it (a toast, the document's own message), and
|
|
47
|
+
// the editor's `console` command must say the same — measured silent before this line.
|
|
48
|
+
editorConsole.error(`Source write rolled back: ${error.message} (${error.code})`, 'history');
|
|
49
|
+
if (activeChromeRegions().drawer !== 'hidden') showWorkspaceUtility(CONSOLE_UTILITY_ID);
|
|
50
|
+
}
|
|
51
|
+
hadSourceFailure = failing;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return () => {
|
|
55
|
+
stopMountFailures();
|
|
56
|
+
stopHistory();
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Toggle the Console utility — the semantic command every menu/hotkey/
|
|
61
|
+
* control-API caller invokes directly. It used to be reached through a
|
|
62
|
+
* `window` CustomEvent (`editor:toggle-console`) installed by
|
|
63
|
+
* `installUtilityEvents`; that indirection was a shell-era relay with no
|
|
64
|
+
* remaining second implementation, so it was deleted. */
|
|
65
|
+
export function toggleConsoleUtility(): void {
|
|
66
|
+
toggleWorkspaceUtility(CONSOLE_UTILITY_ID);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** REVEAL the Console — what a failure item clicks through to. Distinct from
|
|
70
|
+
* {@link toggleConsoleUtility} on purpose: a user acting on a reported error
|
|
71
|
+
* must never have that click HIDE the panel holding the error's trace. */
|
|
72
|
+
export function showConsoleUtility(): void {
|
|
73
|
+
showWorkspaceUtility(CONSOLE_UTILITY_ID);
|
|
74
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace UTILITY registry (W0 — the shell-contract slice of §9 W0).
|
|
3
|
+
* Utilities are the TRANSIENT output/debug surfaces of §1.4/§5: Console,
|
|
4
|
+
* Problems, Build Output, Dev, and story-scoped addon results. They live in
|
|
5
|
+
* the on-demand bottom utility region — never substantial editors, which are
|
|
6
|
+
* documents (`workspace-document-registry.ts`).
|
|
7
|
+
*
|
|
8
|
+
* On-demand is about the TAB: a registration with no materialized tab has no
|
|
9
|
+
* presence at all. Once a tab EXISTS — pre-registered here, contributed by
|
|
10
|
+
* the open project, or introduced by background activity through
|
|
11
|
+
* `ensureWorkspaceUtility` — the region stays on screen COLLAPSED to its own
|
|
12
|
+
* tab strip, so the tab and its badge are discoverable while the body stays
|
|
13
|
+
* closed until the tab is clicked (the layout host owns that presentation).
|
|
14
|
+
*
|
|
15
|
+
* The layout host pre-registers default-visible tabs in a
|
|
16
|
+
* zero-footprint hidden host. Semantic commands and actionable failures reveal
|
|
17
|
+
* that host directly. Other registrations
|
|
18
|
+
* are created on demand (built-ins register via
|
|
19
|
+
* `components/core-utilities.tsx`; migration map).
|
|
20
|
+
*
|
|
21
|
+
* Registrations declare a `section` (`core` | `project`, default `core`) —
|
|
22
|
+
* the editor's own instruments versus the open game's plane. It is the OUTER
|
|
23
|
+
* sort key, so the drawer's tab strip renders the two as visually separated
|
|
24
|
+
* clusters (`utilitySectionBoundaryId` names the divider's position). It is
|
|
25
|
+
* presentation within the one bottom group; it is not a second dock.
|
|
26
|
+
*
|
|
27
|
+
* Idioms mirror `inspector-section-registry.ts`: module-scope state,
|
|
28
|
+
* `useSyncExternalStore`-shaped subscribe + monotonic version,
|
|
29
|
+
* `__resetForTest`, pure-logic headless tests (`Content` is never rendered
|
|
30
|
+
* here). Unlike that registry, utility ids KEY tabs (test ids, persisted
|
|
31
|
+
* drawer state), so duplicate registration is a programming error and
|
|
32
|
+
* throws.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import type { ComponentType } from 'react';
|
|
36
|
+
|
|
37
|
+
/** Attention badge a utility surfaces when its host is open; persistent
|
|
38
|
+
* signals such as Console errors are also projected into the status bar. */
|
|
39
|
+
export interface WorkspaceUtilityBadge {
|
|
40
|
+
readonly count: number;
|
|
41
|
+
readonly severity: 'info' | 'warn' | 'error';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Which audience a utility belongs to, and therefore which cluster of the
|
|
46
|
+
* drawer's tab strip it sits in.
|
|
47
|
+
*
|
|
48
|
+
* - `core` — the EDITOR's own instruments (Console, Animation, Profiler,
|
|
49
|
+
* Network, Audio…). Present in every project.
|
|
50
|
+
* - `project` — the GAME's own plane: one tab per `workspace.utility` tool
|
|
51
|
+
* contribution the open project ships (`tool-loader.ts` registers them
|
|
52
|
+
* under `tool:<contributionId>`). Which tabs exist depends entirely on the
|
|
53
|
+
* open game, so this cluster is empty for a project that contributes none.
|
|
54
|
+
*/
|
|
55
|
+
export type WorkspaceUtilitySection = 'core' | 'project';
|
|
56
|
+
|
|
57
|
+
const SECTION_RANK: Record<WorkspaceUtilitySection, number> = { core: 0, project: 1 };
|
|
58
|
+
|
|
59
|
+
/** The §7 utility contribution contract. */
|
|
60
|
+
export interface WorkspaceUtilityRegistration {
|
|
61
|
+
/** Stable id — keys the drawer tab (`data-testid`, persisted layout). */
|
|
62
|
+
readonly id: string;
|
|
63
|
+
/** Tab label (§8 naming: `Build Output`, not `Build`). */
|
|
64
|
+
readonly title: string;
|
|
65
|
+
/** Tab-strip cluster. Default `'core'` — a contribution that says nothing
|
|
66
|
+
* is one of the editor's own instruments. */
|
|
67
|
+
readonly section?: WorkspaceUtilitySection;
|
|
68
|
+
/** React content host. Never rendered by the registry itself. */
|
|
69
|
+
readonly Content: ComponentType;
|
|
70
|
+
/** Tab order among registered utilities (ascending; ties keep
|
|
71
|
+
* registration order). Default `0`. */
|
|
72
|
+
readonly order?: number;
|
|
73
|
+
/** Session-scoped availability — e.g. Network exists only while a live
|
|
74
|
+
* session exposes the owning adapter (§5 "play-only bottom utility").
|
|
75
|
+
* Default: always available. */
|
|
76
|
+
readonly available?: () => boolean;
|
|
77
|
+
/** Optional attention badge for the tab (may return `null` for none). */
|
|
78
|
+
readonly badge?: () => WorkspaceUtilityBadge | null;
|
|
79
|
+
/** Subscribe to the source read by `badge()`. Dynamic badges must provide
|
|
80
|
+
* this together with `badgeSnapshot` so a dock tab updates while its panel
|
|
81
|
+
* is collapsed. */
|
|
82
|
+
readonly subscribeBadge?: (listener: () => void) => () => void;
|
|
83
|
+
/** Stable `useSyncExternalStore` snapshot for `subscribeBadge`. */
|
|
84
|
+
readonly badgeSnapshot?: () => number;
|
|
85
|
+
/** Whether the tab is pre-registered in the clean layout's hidden utility
|
|
86
|
+
* host. Defaults to `true`; this does not make the host itself visible.
|
|
87
|
+
* Event/output surfaces can remain discoverable while creating their tab
|
|
88
|
+
* only after an explicit command or relevant activity. */
|
|
89
|
+
readonly visibleByDefault?: boolean;
|
|
90
|
+
/** Whether a revealed utility tab may be closed. Defaults to `false`. */
|
|
91
|
+
readonly closeable?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// --- Module-scope state (mirrors inspector-section-registry.ts) -----------
|
|
95
|
+
|
|
96
|
+
interface StoredUtility {
|
|
97
|
+
readonly registration: WorkspaceUtilityRegistration;
|
|
98
|
+
readonly seq: number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let _utilities: StoredUtility[] = [];
|
|
102
|
+
let _seq = 0;
|
|
103
|
+
let _version = 0;
|
|
104
|
+
const _listeners = new Set<() => void>();
|
|
105
|
+
|
|
106
|
+
function notifyChanged(): void {
|
|
107
|
+
_version++;
|
|
108
|
+
for (const fn of _listeners) fn();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Subscribe to (un)registrations. Returns an unsubscribe function. */
|
|
112
|
+
export function subscribeWorkspaceUtilities(fn: () => void): () => void {
|
|
113
|
+
_listeners.add(fn);
|
|
114
|
+
return () => {
|
|
115
|
+
_listeners.delete(fn);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Monotonic change counter — the `getSnapshot` for `useSyncExternalStore`. */
|
|
120
|
+
export function workspaceUtilityRegistryVersion(): number {
|
|
121
|
+
return _version;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Register a utility contribution. Returns an unregister function.
|
|
126
|
+
* Throws on a duplicate id — utility ids key tabs and persisted layout, so
|
|
127
|
+
* two live registrations sharing one id is always a bug (re-registration
|
|
128
|
+
* flows, e.g. project-tool HMR, unregister first — tool-loader's own
|
|
129
|
+
* discipline).
|
|
130
|
+
*/
|
|
131
|
+
export function registerWorkspaceUtility(registration: WorkspaceUtilityRegistration): () => void {
|
|
132
|
+
if (_utilities.some((u) => u.registration.id === registration.id)) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`registerWorkspaceUtility: id "${registration.id}" is already registered — ` +
|
|
135
|
+
'utility ids key drawer tabs and persisted layout, so they must be unique; ' +
|
|
136
|
+
'unregister the previous contribution first.',
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
const stored: StoredUtility = { registration, seq: _seq++ };
|
|
140
|
+
_utilities = [..._utilities, stored];
|
|
141
|
+
notifyChanged();
|
|
142
|
+
return () => {
|
|
143
|
+
if (!_utilities.includes(stored)) return;
|
|
144
|
+
_utilities = _utilities.filter((u) => u !== stored);
|
|
145
|
+
notifyChanged();
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** A registration's cluster, defaulting to the editor's own instruments. */
|
|
150
|
+
export function workspaceUtilitySection(
|
|
151
|
+
registration: WorkspaceUtilityRegistration,
|
|
152
|
+
): WorkspaceUtilitySection {
|
|
153
|
+
return registration.section ?? 'core';
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function sorted(): WorkspaceUtilityRegistration[] {
|
|
157
|
+
return [..._utilities]
|
|
158
|
+
.sort(
|
|
159
|
+
(a, b) =>
|
|
160
|
+
// Section is the OUTER key: the two clusters never interleave, so the
|
|
161
|
+
// tab strip's divider is a single boundary rather than a repeated one.
|
|
162
|
+
SECTION_RANK[workspaceUtilitySection(a.registration)] -
|
|
163
|
+
SECTION_RANK[workspaceUtilitySection(b.registration)] ||
|
|
164
|
+
(a.registration.order ?? 0) - (b.registration.order ?? 0) ||
|
|
165
|
+
a.seq - b.seq,
|
|
166
|
+
)
|
|
167
|
+
.map((u) => u.registration);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The id of the tab the `project` cluster STARTS at, for a given rendered tab
|
|
172
|
+
* order — i.e. the first project-section utility that some core-section
|
|
173
|
+
* utility precedes. `null` when the order has no such boundary (one cluster
|
|
174
|
+
* only, or the project cluster leads). Pure: the caller passes the list it is
|
|
175
|
+
* actually rendering, which after a user tab-drag need not be registry order.
|
|
176
|
+
*/
|
|
177
|
+
export function utilitySectionBoundaryId(
|
|
178
|
+
utilities: readonly WorkspaceUtilityRegistration[],
|
|
179
|
+
): string | null {
|
|
180
|
+
let sawCore = false;
|
|
181
|
+
for (const utility of utilities) {
|
|
182
|
+
if (workspaceUtilitySection(utility) === 'core') {
|
|
183
|
+
sawCore = true;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (sawCore) return utility.id;
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Where a NEWLY ADDED utility tab belongs among the tabs already in the
|
|
193
|
+
* drawer, per registry order — the count of existing tabs that sort at or
|
|
194
|
+
* before it. Registrations arrive at different times (core utilities at
|
|
195
|
+
* module init, project-tool contributions after the async tool load), so
|
|
196
|
+
* appending would interleave the clusters by arrival order; inserting at
|
|
197
|
+
* this index makes any arrival order converge to registry order. Ids the
|
|
198
|
+
* registry no longer knows (a stale persisted tab) sort AFTER every known
|
|
199
|
+
* one, and an unknown `id` appends. Pure: the caller passes the tab ids it
|
|
200
|
+
* is actually hosting, which after a user drag need not be registry order —
|
|
201
|
+
* rank-counting still yields a stable, in-bounds index there.
|
|
202
|
+
*/
|
|
203
|
+
export function utilityInsertionIndex(
|
|
204
|
+
existingIds: readonly string[],
|
|
205
|
+
id: string,
|
|
206
|
+
): number | undefined {
|
|
207
|
+
const rank = new Map(availableWorkspaceUtilities().map((utility, index) => [utility.id, index]));
|
|
208
|
+
const target = rank.get(id);
|
|
209
|
+
if (target === undefined) return undefined;
|
|
210
|
+
let index = 0;
|
|
211
|
+
for (const existing of existingIds) {
|
|
212
|
+
const existingRank = rank.get(existing);
|
|
213
|
+
if (existingRank !== undefined && existingRank <= target) index += 1;
|
|
214
|
+
}
|
|
215
|
+
return index;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Every registered utility, in (order, registration-sequence) order. */
|
|
219
|
+
export function registeredWorkspaceUtilities(): WorkspaceUtilityRegistration[] {
|
|
220
|
+
return sorted();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** The registered utilities whose `available()` currently returns true
|
|
224
|
+
* (guarded: a THROWING `available` counts as unavailable — a broken
|
|
225
|
+
* contribution must not take the drawer down; same failure physics as
|
|
226
|
+
* tool-loader's match guard). */
|
|
227
|
+
export function availableWorkspaceUtilities(): WorkspaceUtilityRegistration[] {
|
|
228
|
+
return sorted().filter((u) => {
|
|
229
|
+
if (!u.available) return true;
|
|
230
|
+
try {
|
|
231
|
+
return u.available();
|
|
232
|
+
} catch {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Order-preserving fingerprint of the available utility ids — a stable
|
|
239
|
+
* STRING, so `useAvailabilitySelector` consumers (the dock's reconciler)
|
|
240
|
+
* re-render only when the available SET changes, not on every 250ms tick. */
|
|
241
|
+
export function availableUtilityFingerprint(): string {
|
|
242
|
+
return availableWorkspaceUtilities()
|
|
243
|
+
.map((u) => u.id)
|
|
244
|
+
.join('\n');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** A utility's current badge (guarded: a throwing `badge` yields `null`). */
|
|
248
|
+
export function workspaceUtilityBadge(id: string): WorkspaceUtilityBadge | null {
|
|
249
|
+
const found = _utilities.find((u) => u.registration.id === id);
|
|
250
|
+
if (!found?.registration.badge) return null;
|
|
251
|
+
try {
|
|
252
|
+
return found.registration.badge();
|
|
253
|
+
} catch {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Test-only reset (mirrors `__resetInspectorSectionRegistryForTest`). */
|
|
259
|
+
export function __resetWorkspaceUtilityRegistryForTest(): void {
|
|
260
|
+
_utilities = [];
|
|
261
|
+
_seq = 0;
|
|
262
|
+
notifyChanged();
|
|
263
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One world-adoption fact. `adopted` fires exactly once, when the trap commits
|
|
3
|
+
* to a (scene, camera, renderer) triple; `alternate` fires for each DISTINCT
|
|
4
|
+
* triple seen afterwards, up to the capture trap's `MAX_RECORDED_ALTERNATES`.
|
|
5
|
+
*/
|
|
6
|
+
export type WorldAdoptionEvent =
|
|
7
|
+
| {
|
|
8
|
+
readonly phase: 'adopted';
|
|
9
|
+
/** `declared` = the contract named this scene; `measured` = first render won. */
|
|
10
|
+
readonly source: 'declared' | 'measured';
|
|
11
|
+
readonly sceneId: string;
|
|
12
|
+
readonly cameraId: string;
|
|
13
|
+
}
|
|
14
|
+
| {
|
|
15
|
+
readonly phase: 'alternate';
|
|
16
|
+
readonly sceneId: string;
|
|
17
|
+
readonly cameraId: string;
|
|
18
|
+
/** `false` ⇒ a SECOND renderer is drawing, which is the stronger signal. */
|
|
19
|
+
readonly sameRenderer: boolean;
|
|
20
|
+
/** Draws observed when this alternate first appeared — how far past the
|
|
21
|
+
* adoption it is, without a wall clock. */
|
|
22
|
+
readonly drawCount: number;
|
|
23
|
+
};
|