@volter/editor-core 0.5.57
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/BUNDLED_NOTICES +1527 -0
- package/LICENSE +686 -0
- package/LICENSE-APACHE +202 -0
- package/NOTICE +18 -0
- package/README.md +24 -0
- package/dist/build/chunk-JS4D4XZ3.js +175 -0
- package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
- package/dist/build/vite-plugin-product-contributions.js +100 -0
- package/dist/build/vite-plugin-product-contributions.js.map +7 -0
- package/dist/build/vite-plugin-shared-react.js +25 -0
- package/dist/build/vite-plugin-shared-react.js.map +7 -0
- package/dist/build/vite-plugin-shared-three.js +86 -0
- package/dist/build/vite-plugin-shared-three.js.map +7 -0
- package/dist/server/chunk-KMJC7AGO.js +98 -0
- package/dist/server/chunk-KMJC7AGO.js.map +7 -0
- package/dist/server/chunk-PSILUMGS.js +46 -0
- package/dist/server/chunk-PSILUMGS.js.map +7 -0
- package/dist/server/frame-proxy.js +255 -0
- package/dist/server/frame-proxy.js.map +7 -0
- package/dist/server/open-browser.js +53 -0
- package/dist/server/open-browser.js.map +7 -0
- package/dist/server/process-shutdown.js +127 -0
- package/dist/server/process-shutdown.js.map +7 -0
- package/dist/server/session-registry.js +141 -0
- package/dist/server/session-registry.js.map +7 -0
- package/dist/server/spawn-opener.js +11 -0
- package/dist/server/spawn-opener.js.map +7 -0
- package/dist/server/worktree-identity.js +11 -0
- package/dist/server/worktree-identity.js.map +7 -0
- package/dist-server/packaged.mjs +88816 -0
- package/package.json +118 -0
- package/scripts/build-plugins.mjs +14 -0
- package/scripts/build-server.mjs +26 -0
- package/scripts/build-session.mjs +9 -0
- package/server/account-credentials.ts +60 -0
- package/server/account-service.ts +1434 -0
- package/server/adapter-region-includes.ts +47 -0
- package/server/asset-catalog-v2.ts +175 -0
- package/server/asset-history-snapshots.ts +196 -0
- package/server/asset-ledger-store.ts +195 -0
- package/server/asset-library-routes.ts +1595 -0
- package/server/blender-wasm-artifact.ts +430 -0
- package/server/boot-timings.ts +106 -0
- package/server/canonical-path.ts +50 -0
- package/server/checkout-workspace-preflight.ts +349 -0
- package/server/cloud-asset-catalog.ts +158 -0
- package/server/coding-inference-launch.ts +237 -0
- package/server/collaboration-account-client.ts +202 -0
- package/server/collaboration-attribution.ts +122 -0
- package/server/collaboration-session.ts +934 -0
- package/server/comfyui-bridge.ts +248 -0
- package/server/console-ledger.ts +499 -0
- package/server/creation-site-transform.ts +304 -0
- package/server/creation-site-write.ts +648 -0
- package/server/data-file-serialize.ts +158 -0
- package/server/editor-brand-html.ts +72 -0
- package/server/editor-control-socket.ts +366 -0
- package/server/editor-server-options.ts +190 -0
- package/server/editor-server.ts +1483 -0
- package/server/editor-sse.ts +352 -0
- package/server/engine-provenance.ts +169 -0
- package/server/engine-source-restart.ts +117 -0
- package/server/frame-bridge.ts +115 -0
- package/server/frame-proxy.ts +490 -0
- package/server/frame-workbench.ts +259 -0
- package/server/frontend-handoff.ts +229 -0
- package/server/game-globals-shadow.ts +113 -0
- package/server/gameplay-session-retention.ts +149 -0
- package/server/gameplay-sessions.ts +123 -0
- package/server/generation-jobs.ts +201 -0
- package/server/generation-reconciler.ts +137 -0
- package/server/generative-execution-context.ts +59 -0
- package/server/git-workflow.ts +612 -0
- package/server/harness-chat-caller.ts +36 -0
- package/server/harness-chat-service.ts +1681 -0
- package/server/idle-shutdown.ts +170 -0
- package/server/js-profiling-policy.ts +52 -0
- package/server/launcher-settings.ts +84 -0
- package/server/local-asset-catalog.ts +410 -0
- package/server/managed-account-defaults.ts +22 -0
- package/server/mock-control-plane.ts +540 -0
- package/server/model-import-conversion.ts +345 -0
- package/server/native-credential-store.ts +162 -0
- package/server/open-browser.ts +118 -0
- package/server/packaged.ts +1192 -0
- package/server/play-stall.ts +126 -0
- package/server/process-shutdown.ts +218 -0
- package/server/product-presets.ts +55 -0
- package/server/project-build-artifact.ts +95 -0
- package/server/project-components.ts +100 -0
- package/server/project-dependency-invalidation.ts +114 -0
- package/server/project-file-scan.ts +235 -0
- package/server/project-hmr-files.ts +215 -0
- package/server/project-install-roots.ts +210 -0
- package/server/project-kinds.ts +71 -0
- package/server/project-mcp-servers.ts +82 -0
- package/server/project-module-freshness.ts +109 -0
- package/server/project-module-instance.ts +375 -0
- package/server/project-optimize-deps-entries.ts +827 -0
- package/server/project-output-writer.ts +679 -0
- package/server/project-package-origin.ts +63 -0
- package/server/project-root-surface.ts +831 -0
- package/server/project-scratch-path.ts +47 -0
- package/server/project-script-hmr.ts +619 -0
- package/server/project-serving-plugins.ts +236 -0
- package/server/project-tools.ts +653 -0
- package/server/project-validation.ts +250 -0
- package/server/project-verbs.ts +127 -0
- package/server/project-view.ts +52 -0
- package/server/project-watch.ts +1134 -0
- package/server/project-work-coordinator.ts +288 -0
- package/server/provider-credentials.ts +331 -0
- package/server/recent-projects-store.ts +98 -0
- package/server/redact-secrets.ts +71 -0
- package/server/repository-presence.ts +267 -0
- package/server/routes/account.ts +357 -0
- package/server/routes/agents.ts +60 -0
- package/server/routes/assets.ts +154 -0
- package/server/routes/build.ts +13 -0
- package/server/routes/collaboration.ts +595 -0
- package/server/routes/configurations.ts +419 -0
- package/server/routes/context.ts +264 -0
- package/server/routes/control-plane.ts +1811 -0
- package/server/routes/logs.ts +272 -0
- package/server/routes/project-identity.ts +302 -0
- package/server/routes/project-open.ts +429 -0
- package/server/routes/project-source.ts +686 -0
- package/server/routes/project-state.ts +383 -0
- package/server/routes/relay.ts +1029 -0
- package/server/routes/route-helpers.ts +29 -0
- package/server/routes/served-modules.ts +138 -0
- package/server/routes/session-tabs.ts +196 -0
- package/server/routes/settings.ts +121 -0
- package/server/routes/share-control.ts +486 -0
- package/server/routes/themes.ts +116 -0
- package/server/routes/tools.ts +230 -0
- package/server/routes/worktrees.ts +595 -0
- package/server/scoped-game-css.ts +461 -0
- package/server/server-utils.ts +1194 -0
- package/server/session-product.ts +112 -0
- package/server/session-registry.ts +230 -0
- package/server/share-claims.ts +138 -0
- package/server/share-host.ts +526 -0
- package/server/share-session-gateway.ts +1362 -0
- package/server/share-tunnel.ts +123 -0
- package/server/spawn-opener.ts +74 -0
- package/server/support/play/log-format.ts +76 -0
- package/server/support/play/session-record.ts +199 -0
- package/server/support/project/build-discipline.ts +718 -0
- package/server/support/project/inspection-node.ts +119 -0
- package/server/support/project/log-naming.ts +54 -0
- package/server/support/project/provenance.ts +290 -0
- package/server/support/project/run-name.ts +18 -0
- package/server/support/project/session-journal.ts +830 -0
- package/server/support/project/shared.ts +327 -0
- package/server/tab-bootstrap.ts +62 -0
- package/server/tab-heartbeat.ts +477 -0
- package/server/tab-lifecycle.ts +550 -0
- package/server/tab-presence.ts +1508 -0
- package/server/team-agent-mirror.ts +95 -0
- package/server/twin-auth.ts +138 -0
- package/server/vendored-lock-recorder.ts +968 -0
- package/server/worktree-identity.ts +121 -0
- package/server/worktree-management.ts +398 -0
- package/server/worktree-retention.d.mts +13 -0
- package/server/worktree-retention.mjs +205 -0
- package/src/EditorContext.tsx +169 -0
- package/src/account.ts +333 -0
- package/src/action-registry.ts +532 -0
- package/src/active-product.ts +74 -0
- package/src/active-project.ts +155 -0
- package/src/adapter-editor-config.ts +25 -0
- package/src/adapter-observation.ts +49 -0
- package/src/animation/stage-transport.ts +379 -0
- package/src/animation/three-clips-subject.ts +172 -0
- package/src/api/asset-library-wire.ts +45 -0
- package/src/api/assets.ts +365 -0
- package/src/api/base.ts +10 -0
- package/src/api/build.ts +99 -0
- package/src/api/git-wire.ts +56 -0
- package/src/api/logs.ts +92 -0
- package/src/api/project-identity.ts +74 -0
- package/src/api/project-open.ts +355 -0
- package/src/api/project-source.ts +162 -0
- package/src/api/project-state.ts +107 -0
- package/src/api/relay.ts +268 -0
- package/src/api/settings.ts +36 -0
- package/src/api/themes.ts +45 -0
- package/src/api/worktrees.ts +257 -0
- package/src/asset-compare-core.ts +171 -0
- package/src/asset-compare.ts +294 -0
- package/src/asset-editor-context.tsx +100 -0
- package/src/asset-events.ts +97 -0
- package/src/asset-inspector-actions.ts +87 -0
- package/src/asset-preview-framing.ts +357 -0
- package/src/asset-preview.ts +2802 -0
- package/src/asset-selection-viewer-registry.ts +113 -0
- package/src/asset-selection.ts +133 -0
- package/src/asset-workflow/asset-capabilities.ts +344 -0
- package/src/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/asset-workflow/asset-ledger.ts +156 -0
- package/src/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/asset-workflow/asset-types.ts +142 -0
- package/src/asset-workflow/asset-workflow-quality.ts +61 -0
- package/src/asset-workflow/audio-preview-player.ts +193 -0
- package/src/asset-workflow/audio-waveform.ts +22 -0
- package/src/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/asset-workflow/folder-preview.ts +345 -0
- package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/asset-workflow/image-view-scale.ts +32 -0
- package/src/asset-workflow/import-contract.ts +124 -0
- package/src/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/asset-workflow/model-inspection.ts +818 -0
- package/src/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +139 -0
- package/src/asset-workflow/project-asset-operations.ts +154 -0
- package/src/asset-workflow/project-asset-roots.ts +68 -0
- package/src/asset-workflow/project-content.ts +288 -0
- package/src/asset-workflow/project-source-index.ts +550 -0
- package/src/asset-workflow/thumbnail-system.ts +256 -0
- package/src/authoring/active-adapter.ts +199 -0
- package/src/authoring/active-systems.ts +422 -0
- package/src/authoring/adapter-key.ts +18 -0
- package/src/authoring/authoring-asset-url.ts +27 -0
- package/src/authoring/bootstrap-state.ts +49 -0
- package/src/authoring/boundary-authoring-adapter.ts +184 -0
- package/src/authoring/breakpoint-state.ts +43 -0
- package/src/authoring/canvas-scene-guides.ts +76 -0
- package/src/authoring/component-instance-root.ts +171 -0
- package/src/authoring/composite-authoring-adapter.ts +2110 -0
- package/src/authoring/consumer-actions.ts +520 -0
- package/src/authoring/css-numeric-style.ts +97 -0
- package/src/authoring/design-time-layers.ts +849 -0
- package/src/authoring/design-time-mount-registry.ts +235 -0
- package/src/authoring/design-time-settle.ts +343 -0
- package/src/authoring/edit-mode-authoring.ts +619 -0
- package/src/authoring/eyedropper-session.ts +60 -0
- package/src/authoring/instance-source-menu-register.ts +13 -0
- package/src/authoring/instance-source-menu.ts +135 -0
- package/src/authoring/layered-pick.ts +183 -0
- package/src/authoring/live-gesture-lock.ts +50 -0
- package/src/authoring/live-object-transform.ts +62 -0
- package/src/authoring/mount-failure-report.ts +154 -0
- package/src/authoring/mounted-root-subjects.ts +144 -0
- package/src/authoring/no-authoring-adapter.ts +55 -0
- package/src/authoring/null-inspection-subjects.tsx +75 -0
- package/src/authoring/object3d-document-persistence.ts +106 -0
- package/src/authoring/object3d-document-session-registry.ts +120 -0
- package/src/authoring/object3d-document-session.ts +1326 -0
- package/src/authoring/object3d-gesture-controller.ts +113 -0
- package/src/authoring/panel-authoring.ts +121 -0
- package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
- package/src/authoring/prefab-instance-section-model.ts +55 -0
- package/src/authoring/project-authoring-session.ts +105 -0
- package/src/authoring/provenance.ts +99 -0
- package/src/authoring/quarks-particle-systems.ts +19 -0
- package/src/authoring/react-canvas-navigation.ts +255 -0
- package/src/authoring/react-design-canvas-style.ts +20 -0
- package/src/authoring/react-story-board.ts +937 -0
- package/src/authoring/selection-scope.ts +195 -0
- package/src/authoring/shell-document-ops.ts +169 -0
- package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
- package/src/authoring/shell-viewport-policy.ts +48 -0
- package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
- package/src/authoring/stories-scope.ts +35 -0
- package/src/authoring/story-board-chrome-fit.ts +107 -0
- package/src/authoring/story-board-presentation.ts +111 -0
- package/src/authoring/three-projection-core.ts +226 -0
- package/src/authoring/viewport-pick-context.ts +40 -0
- package/src/authoring/viewport-raycast.ts +240 -0
- package/src/authoring/viewport-tool-context.ts +73 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +152 -0
- package/src/authoring/world-pan-state.ts +198 -0
- package/src/authoring/world-session-state.ts +101 -0
- package/src/authoring/write-pipe.ts +173 -0
- package/src/availability-tick.ts +66 -0
- package/src/bitmap-label.ts +120 -0
- package/src/blender-tab-metrics.ts +161 -0
- package/src/board-open-actions.ts +20 -0
- package/src/boot-routing.ts +391 -0
- package/src/build-identity.ts +15 -0
- package/src/bytes-codec.ts +62 -0
- package/src/camera-authoring.ts +175 -0
- package/src/cancellation-reason.ts +58 -0
- package/src/canvas-preview-frames.ts +482 -0
- package/src/capture-camera-pose.ts +77 -0
- package/src/chrome-registry.ts +159 -0
- package/src/chrome-slot-registry.ts +91 -0
- package/src/collaboration-client.ts +264 -0
- package/src/collaboration-presence.ts +41 -0
- package/src/command-dispatch.ts +19 -0
- package/src/command-listener.ts +2743 -0
- package/src/command-registry.ts +70 -0
- package/src/component-board-registry.ts +205 -0
- package/src/component-states-registry.ts +200 -0
- package/src/components/AgentPresentationNotice.tsx +75 -0
- package/src/components/AlignToolbar.tsx +204 -0
- package/src/components/AppRoot.tsx +394 -0
- package/src/components/ApplicationMenus.tsx +415 -0
- package/src/components/AssetBrowser.tsx +2843 -0
- package/src/components/AssetEditorShell.tsx +216 -0
- package/src/components/AssetInspectorToolSection.tsx +124 -0
- package/src/components/BoardRulers.tsx +354 -0
- package/src/components/CameraInfo.tsx +81 -0
- package/src/components/CanvasSceneViewport.tsx +556 -0
- package/src/components/CapabilityCoverageSection.tsx +185 -0
- package/src/components/CenterDocuments.tsx +22 -0
- package/src/components/ChromeSlot.tsx +20 -0
- package/src/components/CodeView.tsx +470 -0
- package/src/components/CollaborationHeaderControl.css +74 -0
- package/src/components/CompactInspectorCard.tsx +190 -0
- package/src/components/CompactInspectorShell.tsx +39 -0
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +270 -0
- package/src/components/DefaultEditorLayout.tsx +106 -0
- package/src/components/DocumentHeaderStrip.tsx +96 -0
- package/src/components/DocumentShelfRail.tsx +45 -0
- package/src/components/DocumentThumbnail.tsx +345 -0
- package/src/components/EditorLeaseGuard.tsx +372 -0
- package/src/components/ErrorBanner.tsx +123 -0
- package/src/components/FolderPreviewTile.tsx +159 -0
- package/src/components/GameHierarchy.tsx +3842 -0
- package/src/components/GameplaySessionTimeline.tsx +295 -0
- package/src/components/InspectionProjection.tsx +968 -0
- package/src/components/Inspector.tsx +233 -0
- package/src/components/InspectorCanvasPreview.tsx +35 -0
- package/src/components/InspectorFieldsSection.tsx +290 -0
- package/src/components/InspectorObjectPreview.tsx +57 -0
- package/src/components/InspectorStoriesSection.tsx +92 -0
- package/src/components/InspectorToolSection.tsx +96 -0
- package/src/components/InspectorTransformSection.tsx +245 -0
- package/src/components/LightExplorerPanel.tsx +433 -0
- package/src/components/MediaProperties.tsx +145 -0
- package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
- package/src/components/Object3DDocumentToolbar.css +100 -0
- package/src/components/Object3DDocumentToolbar.tsx +454 -0
- package/src/components/Object3DDocumentViewport.tsx +58 -0
- package/src/components/ProjectHeader.css +617 -0
- package/src/components/ProjectHeader.tsx +328 -0
- package/src/components/ProjectLayout.tsx +249 -0
- package/src/components/ReactCanvasControls.tsx +284 -0
- package/src/components/RootSelectionOverlay.tsx +3162 -0
- package/src/components/RootTextEditor.tsx +79 -0
- package/src/components/SaveStatus.tsx +70 -0
- package/src/components/StageHost.tsx +1954 -0
- package/src/components/StageOverlays.tsx +21 -0
- package/src/components/StartupErrorScreen.tsx +76 -0
- package/src/components/StartupLoadingScreen.tsx +65 -0
- package/src/components/StatsOverlay.tsx +78 -0
- package/src/components/SurfaceStateOverlay.tsx +24 -0
- package/src/components/ToolContributionSurfaces.tsx +65 -0
- package/src/components/ToolHost.tsx +370 -0
- package/src/components/ToolObject3DPreview.tsx +39 -0
- package/src/components/Toolbar.tsx +595 -0
- package/src/components/TransientHint.tsx +44 -0
- package/src/components/TransportStrip.tsx +174 -0
- package/src/components/VersionControlSection.tsx +470 -0
- package/src/components/VgaiLogo.css +83 -0
- package/src/components/VgaiLogo.tsx +35 -0
- package/src/components/ViewportControlsHint.tsx +60 -0
- package/src/components/ViewportFurniture.tsx +401 -0
- package/src/components/ViewportOverlay.tsx +145 -0
- package/src/components/ViewportOverlaysMenu.tsx +153 -0
- package/src/components/ViewportShadingMenu.tsx +300 -0
- package/src/components/ViewportViewMenu.tsx +101 -0
- package/src/components/WorkspaceDocumentSurface.tsx +204 -0
- package/src/components/WorkspaceUtilitySurface.tsx +22 -0
- package/src/components/WorktreeSwitcher.css +239 -0
- package/src/components/WorktreeSwitcher.tsx +890 -0
- package/src/components/account-documents.tsx +1162 -0
- package/src/components/asset-documents.tsx +812 -0
- package/src/components/asset-editor-persistence.ts +216 -0
- package/src/components/asset-selection-section.tsx +535 -0
- package/src/components/asset-thumbnails.tsx +312 -0
- package/src/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
- package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
- package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
- package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
- package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
- package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
- package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
- package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
- package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
- package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
- package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/components/asset-viewers/shader-source.ts +144 -0
- package/src/components/asset-workflow.css +731 -0
- package/src/components/board-guides.ts +150 -0
- package/src/components/compact-inspector.css +539 -0
- package/src/components/core-utilities.tsx +90 -0
- package/src/components/editor-notifications.css +40 -0
- package/src/components/engine-workspace.css +274 -0
- package/src/components/inspector-preview-section.tsx +238 -0
- package/src/components/inspector-property-grouping.ts +64 -0
- package/src/components/inspector-revert-label.ts +20 -0
- package/src/components/inspector-selection.ts +42 -0
- package/src/components/inspector-stories-gating.ts +171 -0
- package/src/components/inspector-transform-subject.ts +11 -0
- package/src/components/inspector-transform.ts +75 -0
- package/src/components/kind-documents.tsx +500 -0
- package/src/components/palette-action-publisher.tsx +140 -0
- package/src/components/primitives/DraftColorInput.tsx +74 -0
- package/src/components/product-shell.css +1829 -0
- package/src/components/project-tool-documents.tsx +410 -0
- package/src/components/scene-documents.tsx +223 -0
- package/src/components/stage-keyboard.tsx +37 -0
- package/src/components/stage-overlay-set.tsx +107 -0
- package/src/components/stage-presence-markers.ts +478 -0
- package/src/components/standard-viewport-dressing.ts +417 -0
- package/src/components/status-contributions.tsx +403 -0
- package/src/components/tool-documents.tsx +309 -0
- package/src/components/tool-schema-form.tsx +262 -0
- package/src/components/use-after-paint.ts +41 -0
- package/src/components/use-project-image-assets.ts +86 -0
- package/src/components/viewport-header-controls.css +90 -0
- package/src/components/viewport-surface-status.tsx +55 -0
- package/src/components/workspace-history.ts +32 -0
- package/src/components/workspace-static-panel-registry.tsx +152 -0
- package/src/components/workspace-surfaces.css +621 -0
- package/src/components/world-documents.tsx +586 -0
- package/src/components/world-overlay-gestures.ts +1694 -0
- package/src/composite-screenshot.ts +1641 -0
- package/src/console-sync.ts +131 -0
- package/src/constraint-helper.ts +338 -0
- package/src/content-entry-source-registry.ts +184 -0
- package/src/coverage/authoring-seam-evidence.ts +300 -0
- package/src/coverage/canvas-reveal.ts +192 -0
- package/src/coverage/design-time-surfaces.ts +101 -0
- package/src/coverage/live-seam-evidence.ts +11 -0
- package/src/coverage/ontology-invariants.ts +466 -0
- package/src/coverage/session-vitals.ts +501 -0
- package/src/coverage/system-seam-evidence.ts +72 -0
- package/src/crash-null-boundary.ts +36 -0
- package/src/creation-site-edit.ts +1479 -0
- package/src/creation-site-registry.ts +160 -0
- package/src/delegate-harness-registry.ts +143 -0
- package/src/document-context-registry.ts +177 -0
- package/src/document-open-registry.ts +200 -0
- package/src/document-preview-source.ts +20 -0
- package/src/document-renderer-session.ts +138 -0
- package/src/editor-api.ts +46 -0
- package/src/editor-chrome-capture.ts +139 -0
- package/src/editor-commands.ts +164 -0
- package/src/editor-console.ts +563 -0
- package/src/editor-current-view.ts +82 -0
- package/src/editor-document-probe.ts +881 -0
- package/src/editor-git-client.ts +115 -0
- package/src/editor-host-door.ts +462 -0
- package/src/editor-hotkeys.ts +842 -0
- package/src/editor-lease-view.ts +39 -0
- package/src/editor-lease.ts +415 -0
- package/src/editor-mode.ts +19 -0
- package/src/editor-notifications.ts +140 -0
- package/src/editor-presence.ts +563 -0
- package/src/editor-presentation-activity.ts +50 -0
- package/src/editor-presentation-notice.ts +42 -0
- package/src/editor-runtime.tsx +145 -0
- package/src/editor-server-response.ts +86 -0
- package/src/editor-session-attribution.ts +75 -0
- package/src/editor-session-mode.ts +54 -0
- package/src/editor-shell-store.ts +1304 -0
- package/src/editor-state-facets.ts +74 -0
- package/src/editor-styles.css +33 -0
- package/src/editor-view-presentation.ts +810 -0
- package/src/editor-viewport.ts +5302 -0
- package/src/entity-lod.ts +31 -0
- package/src/entity-object.ts +91 -0
- package/src/files/file-provider.ts +62 -0
- package/src/files/project-files.ts +264 -0
- package/src/finders/index.ts +136 -0
- package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/frame/bridge.tsx +1408 -0
- package/src/frame/product.ts +77 -0
- package/src/gameplay-dom-recording.ts +319 -0
- package/src/gameplay-export-state.ts +14 -0
- package/src/gameplay-replay.ts +417 -0
- package/src/gameplay-session-time.ts +9 -0
- package/src/gameplay-sessions.ts +204 -0
- package/src/harness-chat-types.ts +253 -0
- package/src/hierarchy-component-marks.ts +298 -0
- package/src/hierarchy-drop.ts +91 -0
- package/src/hierarchy-expansion-state.ts +80 -0
- package/src/hierarchy-header-slot.ts +52 -0
- package/src/hierarchy-internals.ts +197 -0
- package/src/hierarchy-kind-icon.ts +217 -0
- package/src/hierarchy-mark-reader.ts +73 -0
- package/src/hierarchy-menu-registry.ts +67 -0
- package/src/hierarchy-node-rows.ts +307 -0
- package/src/hierarchy-panel-view.ts +280 -0
- package/src/hierarchy-projection.ts +76 -0
- package/src/hierarchy-row-cache.ts +243 -0
- package/src/hierarchy-row-model.ts +308 -0
- package/src/hierarchy-rows.ts +11 -0
- package/src/hierarchy-walk.ts +86 -0
- package/src/history/editor-session.ts +25 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-delegate.ts +163 -0
- package/src/history/history-limit-notices.ts +43 -0
- package/src/history/history-service.ts +1173 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +386 -0
- package/src/history/project-root-history-backends.ts +139 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +103 -0
- package/src/history/source-history-backend.ts +546 -0
- package/src/history/types.ts +124 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hotkeys.ts +188 -0
- package/src/inference-diagnostics.ts +69 -0
- package/src/initial-project.ts +80 -0
- package/src/inspection/active-subject.ts +578 -0
- package/src/inspection/active-surface.ts +142 -0
- package/src/inspection/compose.ts +1064 -0
- package/src/inspection/display.ts +170 -0
- package/src/inspection/document-subject.ts +109 -0
- package/src/inspection/game-subject.ts +85 -0
- package/src/inspection/model.ts +542 -0
- package/src/inspection/null-subject.ts +115 -0
- package/src/inspection/serialize.ts +357 -0
- package/src/inspection/use-active-inspection.ts +180 -0
- package/src/inspector-presentation.ts +201 -0
- package/src/inspector-section-registry.ts +221 -0
- package/src/instance-source-actions.ts +163 -0
- package/src/instanced-presentation.ts +164 -0
- package/src/js-heap.ts +71 -0
- package/src/key-actions.ts +91 -0
- package/src/keymap-presets.ts +401 -0
- package/src/layout-policy.ts +31 -0
- package/src/learn-links.ts +73 -0
- package/src/light-explorer-model.ts +134 -0
- package/src/live-canvas-frame.ts +55 -0
- package/src/live-document.ts +279 -0
- package/src/live-module-source.ts +230 -0
- package/src/live-session-registry.ts +220 -0
- package/src/live-transition.ts +633 -0
- package/src/manifest-project.ts +107 -0
- package/src/model-thumbnail.ts +523 -0
- package/src/native-selection-style.ts +202 -0
- package/src/object3d-document-write-policy.ts +137 -0
- package/src/packaged-runtime.ts +108 -0
- package/src/palettes/maya.palette.json +57 -0
- package/src/palettes/substance.palette.json +57 -0
- package/src/pasteboard-module.ts +81 -0
- package/src/performance-profiler.ts +367 -0
- package/src/performance-sources.ts +69 -0
- package/src/play-boot-phase.ts +145 -0
- package/src/presentation-surface.ts +248 -0
- package/src/project-adapter.ts +1143 -0
- package/src/project-asset-refresh.ts +26 -0
- package/src/project-declaration-refresh.ts +31 -0
- package/src/project-local-state.ts +118 -0
- package/src/project-manager.ts +243 -0
- package/src/project-module-changes.ts +163 -0
- package/src/project-module-split.ts +266 -0
- package/src/project-provenance.ts +115 -0
- package/src/project-ready.ts +42 -0
- package/src/project-session-reset.ts +67 -0
- package/src/project-shape.ts +68 -0
- package/src/project-tool-discovery.ts +66 -0
- package/src/project-tools.ts +107 -0
- package/src/project-work-types.ts +149 -0
- package/src/projection/three.ts +898 -0
- package/src/projection/types.ts +44 -0
- package/src/readiness.ts +113 -0
- package/src/reflection-probe-helper.ts +142 -0
- package/src/reported-play-state.ts +90 -0
- package/src/resolve-relative-specifier.ts +33 -0
- package/src/scene-document-plan.ts +315 -0
- package/src/scene-framing.ts +315 -0
- package/src/scene-live-open.ts +210 -0
- package/src/scene-view-fog.ts +89 -0
- package/src/scoped-game-css.ts +152 -0
- package/src/session-orphan-record.ts +193 -0
- package/src/session-tombstone.ts +126 -0
- package/src/settings/settings-provider.ts +82 -0
- package/src/settings-store.ts +345 -0
- package/src/shared-view-restore.ts +42 -0
- package/src/shell-store-door.ts +45 -0
- package/src/source-conflict.ts +122 -0
- package/src/spatial-handle-visuals.ts +332 -0
- package/src/stage-context.ts +341 -0
- package/src/stage-store-registry.ts +63 -0
- package/src/stale-chunk-recovery.ts +34 -0
- package/src/state-report-deferral.ts +73 -0
- package/src/storage/host-files-storage.ts +97 -0
- package/src/storage/http-storage.ts +174 -0
- package/src/storage/index.ts +75 -0
- package/src/storage/mem-storage.ts +149 -0
- package/src/storage/path-lock.ts +44 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/types.ts +116 -0
- package/src/stories/StoryComponentThumbnail.tsx +184 -0
- package/src/stories/StoryPreviewMount.tsx +306 -0
- package/src/stories/component-content-source.tsx +106 -0
- package/src/stories/component-states-source.ts +78 -0
- package/src/stories/compose-project-stories.ts +255 -0
- package/src/stories/pixi-story-model.ts +30 -0
- package/src/stories/prefabs-finder.ts +54 -0
- package/src/stories/prefabs-from-stories.ts +182 -0
- package/src/stories/project-story-discovery.ts +78 -0
- package/src/stories/project-story-regions.ts +24 -0
- package/src/stories/story-actions.ts +54 -0
- package/src/stories/story-capture-command.ts +124 -0
- package/src/stories/story-capture.ts +584 -0
- package/src/stories/story-declared-medium.ts +126 -0
- package/src/stories/story-discovery.ts +176 -0
- package/src/stories/story-document-openers.ts +36 -0
- package/src/stories/story-dom-runtime.ts +78 -0
- package/src/stories/story-grouping.ts +111 -0
- package/src/stories/story-lane.ts +88 -0
- package/src/stories/story-mount-turn.ts +27 -0
- package/src/stories/story-opener.ts +260 -0
- package/src/stories/story-pixi-preview.ts +408 -0
- package/src/stories/story-presentation.ts +215 -0
- package/src/stories/story-registry.ts +517 -0
- package/src/stories/story-three-preview.ts +807 -0
- package/src/stories/three-story-model.ts +96 -0
- package/src/story-three-preview-runtime.ts +56 -0
- package/src/surface-keyboard.ts +112 -0
- package/src/surface-state.ts +124 -0
- package/src/tab-bootstrap.js +628 -0
- package/src/tab-census.ts +198 -0
- package/src/tab-lifecycle-client.ts +196 -0
- package/src/theme-library.ts +844 -0
- package/src/theme-preference.ts +378 -0
- package/src/theme.css +3437 -0
- package/src/three-viewport/bone-selection-highlight.ts +119 -0
- package/src/three-viewport/camera-fit.ts +41 -0
- package/src/three-viewport/interactive-renderer.ts +132 -0
- package/src/three-viewport/selection-brackets.ts +310 -0
- package/src/three-viewport/selection-outline.ts +183 -0
- package/src/three-viewport/skeleton-helper.ts +61 -0
- package/src/three-viewport/source-color.ts +167 -0
- package/src/three-viewport/studio-environment.ts +96 -0
- package/src/three-viewport-presentation.ts +23 -0
- package/src/tool-contribution-play.ts +74 -0
- package/src/tool-loader.ts +1798 -0
- package/src/transform-mode-request.ts +57 -0
- package/src/transient-hint.ts +78 -0
- package/src/trigger-volume-helper.ts +116 -0
- package/src/ui-source/adapter-region-includes.ts +241 -0
- package/src/ui-source/ensure-import.ts +132 -0
- package/src/ui-source/file-region-resolver.ts +302 -0
- package/src/ui-source/inspect.ts +775 -0
- package/src/ui-source/oid-transform.ts +1845 -0
- package/src/ui-source/plan-csf-story.ts +196 -0
- package/src/ui-source/plan-extract-component.ts +421 -0
- package/src/ui-source/plan-fork-component.ts +621 -0
- package/src/ui-source/plan-named-style.ts +95 -0
- package/src/ui-source/plan-source-edit.ts +353 -0
- package/src/ui-source/r3f-contract-resolver.ts +327 -0
- package/src/ui-source/r3f-diagnostic-index.ts +165 -0
- package/src/ui-source/r3f-environment-binding.ts +133 -0
- package/src/ui-source/r3f-joint-binding.ts +251 -0
- package/src/ui-source/r3f-lod-binding.ts +91 -0
- package/src/ui-source/r3f-particle-binding.ts +235 -0
- package/src/ui-source/r3f-physics-binding.ts +483 -0
- package/src/ui-source/r3f-project-contracts.ts +444 -0
- package/src/ui-source/relative-import-specifier.ts +34 -0
- package/src/ui-source/reparent-guard.ts +544 -0
- package/src/ui-source/source-edit-request.ts +97 -0
- package/src/ui-source/source-write-backend.ts +618 -0
- package/src/ui-source/syntactic-prop-specs.ts +296 -0
- package/src/ui-source/tier-source-write-backend.ts +279 -0
- package/src/ui-source/ts-ast.ts +171 -0
- package/src/ui-source/utility-class-support.ts +169 -0
- package/src/ui-source/write-component-default.ts +133 -0
- package/src/ui-source/writer.ts +1989 -0
- package/src/viewport-activation-timings.ts +840 -0
- package/src/viewport-authoring-policy.ts +186 -0
- package/src/viewport-controls-hint.ts +57 -0
- package/src/viewport-door.ts +237 -0
- package/src/viewport-shading-boundary.ts +12 -0
- package/src/vite-error-surface.ts +141 -0
- package/src/wait-until.ts +37 -0
- package/src/workspace-areas.ts +156 -0
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-available-documents.ts +127 -0
- package/src/workspace-core-utilities.ts +31 -0
- package/src/workspace-document-ids.ts +59 -0
- package/src/workspace-document-registry.ts +612 -0
- package/src/workspace-document-restore.ts +145 -0
- package/src/workspace-host-commands.ts +141 -0
- package/src/workspace-persistence-gate.ts +40 -0
- package/src/workspace-play-utilities.ts +44 -0
- package/src/workspace-presets.ts +425 -0
- package/src/workspace-regions.ts +294 -0
- package/src/workspace-state-persistence.ts +536 -0
- package/src/workspace-static-panels.ts +73 -0
- package/src/workspace-status-registry.ts +121 -0
- package/src/workspace-style.ts +239 -0
- package/src/workspace-utility-commands.ts +74 -0
- package/src/workspace-utility-registry.ts +263 -0
- package/src/workspace-viewport-rect.ts +97 -0
- package/src/world-adoption.ts +115 -0
- package/src/world-document-routing.ts +104 -0
- package/vite-plugin-creation-site-write.ts +184 -0
- package/vite-plugin-creation-site.ts +80 -0
- package/vite-plugin-game-static.ts +303 -0
- package/vite-plugin-module-doorways.ts +336 -0
- package/vite-plugin-product-contributions.ts +197 -0
- package/vite-plugin-project-game-static.ts +125 -0
- package/vite-plugin-project-jsx-js.ts +65 -0
- package/vite-plugin-project-root-absolute-assets.ts +359 -0
- package/vite-plugin-shared-react.ts +420 -0
- package/vite-plugin-shared-three.ts +203 -0
- package/vite-plugin-ui-oid.ts +2106 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE SESSION OWNS THE FRAME. This module is where it does.
|
|
3
|
+
*
|
|
4
|
+
* `vgai edit` IS the Code-OSS workbench, and the workbench is two things: the
|
|
5
|
+
* remote extension host (a child process, serving the VS Code page) and the
|
|
6
|
+
* one-origin proxy (a listener in THIS process, `frame-proxy.ts`). Both belong
|
|
7
|
+
* to the session, which is the only owner that can be right: they exist to
|
|
8
|
+
* serve this project's session, they must die when it does, and a `vgai edit`
|
|
9
|
+
* that merely REUSES a live session must not have to adopt somebody else's
|
|
10
|
+
* children.
|
|
11
|
+
*
|
|
12
|
+
* RESOURCE OWNERSHIP, stated once (the rule that cost a game-scoped clock).
|
|
13
|
+
* - OWNER: this session process. It spawns the REH into its own process group
|
|
14
|
+
* and listens for the proxy itself.
|
|
15
|
+
* - SHARERS: none. The CLI allocates the two reserved ports and hands them
|
|
16
|
+
* over; after that it owns nothing of the frame. A second `vgai edit` on
|
|
17
|
+
* this project reuses the session and therefore reuses the frame.
|
|
18
|
+
* - THE ONE TEARDOWN: the host's shutdown task list (`dev.ts`/`packaged.ts`'s
|
|
19
|
+
* `createProcessShutdown`), which is the same path `vgai close`, SIGTERM and
|
|
20
|
+
* the idle timer all take — the path that already ends run configurations.
|
|
21
|
+
* Nothing else may stop it.
|
|
22
|
+
*
|
|
23
|
+
* WHERE THE WORKBENCH IS comes from the project's own declaration
|
|
24
|
+
* (`.vgai/workbench.json`) or `vgai edit --workbench <dir>`; the CLI resolves it
|
|
25
|
+
* once to refuse early and passes the directory here. `@volter/editor-sdk/session/
|
|
26
|
+
* workbench-locator` is the one resolver and the one set of refusal texts.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { type ChildProcess, spawn } from 'node:child_process';
|
|
30
|
+
import { createConnection } from 'node:net';
|
|
31
|
+
import { workbenchProductId } from '@volter/editor-sdk/session/product-locator';
|
|
32
|
+
import {
|
|
33
|
+
resolveWorkbench,
|
|
34
|
+
type WorkbenchIdentity,
|
|
35
|
+
workbenchUrl,
|
|
36
|
+
} from '@volter/editor-sdk/session/workbench-locator';
|
|
37
|
+
import { startFrameProxy } from './frame-proxy';
|
|
38
|
+
import { stopProcess } from './process-shutdown';
|
|
39
|
+
import { sessionProduct } from './session-product';
|
|
40
|
+
|
|
41
|
+
/** The workbench directory the CLI resolved and handed over. */
|
|
42
|
+
const WORKBENCH_DIR_ENV = 'VGAI_WORKBENCH_DIR';
|
|
43
|
+
/** The reserved port for the Code-OSS server. */
|
|
44
|
+
const FRAME_PORT_ENV = 'VGAI_FRAME_PORT';
|
|
45
|
+
/** The reserved port for the one-origin proxy — the url a person opens. */
|
|
46
|
+
const FRAME_PROXY_PORT_ENV = 'VGAI_FRAME_PROXY_PORT';
|
|
47
|
+
|
|
48
|
+
export interface FrameLaunch {
|
|
49
|
+
readonly workbenchDir: string;
|
|
50
|
+
readonly rehPort: number;
|
|
51
|
+
readonly proxyPort: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* What this session was told to frame, or `null` when it was told nothing.
|
|
56
|
+
* Reading the three together is deliberate: a launch with a workbench and no
|
|
57
|
+
* ports, or ports and no workbench, is a caller bug and reads as "not framed"
|
|
58
|
+
* rather than as half a frame.
|
|
59
|
+
*/
|
|
60
|
+
export function frameLaunchFromEnv(): FrameLaunch | null {
|
|
61
|
+
const workbenchDir = process.env[WORKBENCH_DIR_ENV];
|
|
62
|
+
const rehPort = Number(process.env[FRAME_PORT_ENV]);
|
|
63
|
+
const proxyPort = Number(process.env[FRAME_PROXY_PORT_ENV]);
|
|
64
|
+
if (!workbenchDir || !Number.isInteger(rehPort) || !Number.isInteger(proxyPort)) return null;
|
|
65
|
+
return { workbenchDir, rehPort, proxyPort };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The url the workbench will answer on, known before anything starts.
|
|
70
|
+
*
|
|
71
|
+
* The tab bijection needs it at `createEditorServer` time — under the frame the
|
|
72
|
+
* session's ONE tab is the workbench page, not this server's own — and it is
|
|
73
|
+
* pure arithmetic over the reserved port, so nothing has to have booted yet.
|
|
74
|
+
*/
|
|
75
|
+
export function frameWorkbenchUrl(launch: FrameLaunch, projectRoot: string): string {
|
|
76
|
+
return workbenchUrl(launch.proxyPort, projectRoot);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface FrameWorkbench {
|
|
80
|
+
/** What this session is running, for `EditorState.workbench` and `vgai status`. */
|
|
81
|
+
readonly identity: WorkbenchIdentity;
|
|
82
|
+
readonly url: string;
|
|
83
|
+
/**
|
|
84
|
+
* STOP THE CODE-OSS SERVER — the detached CHILD, and the one thing here that
|
|
85
|
+
* can outlive this process. Unconditional in the shutdown list: it waits on
|
|
86
|
+
* nothing, least of all a tab (`dev.ts`'s task list).
|
|
87
|
+
*/
|
|
88
|
+
stopServer(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* CLOSE THE ONE-ORIGIN PROXY — a listener in THIS process, and the tab's only
|
|
91
|
+
* route to this session: the page's origin is the proxy's, so every
|
|
92
|
+
* `/__editor/*` call it makes, the tab-close ACK BEACON included, arrives
|
|
93
|
+
* here first. So it closes with the HTTP server, AFTER the tab-close notice,
|
|
94
|
+
* and not with the child above. Measured 2026-09-21: closing it beside the
|
|
95
|
+
* child turned every `vgai close` from `session-end-acked … ms 26` into
|
|
96
|
+
* `session-end-unacked … ms 2002` — the page was told, closed itself, and
|
|
97
|
+
* its beacon had nowhere to land.
|
|
98
|
+
*/
|
|
99
|
+
closeProxy(): Promise<void>;
|
|
100
|
+
/** Both, in one call — for the boot error path and the source-restart exit,
|
|
101
|
+
* where there is no tab to preserve a route for. */
|
|
102
|
+
stop(): Promise<void>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** True while something is listening on `port` of loopback. */
|
|
106
|
+
function portTaken(port: number): Promise<boolean> {
|
|
107
|
+
return new Promise((done) => {
|
|
108
|
+
const socket = createConnection({ host: '127.0.0.1', port });
|
|
109
|
+
const settle = (taken: boolean) => {
|
|
110
|
+
socket.destroy();
|
|
111
|
+
done(taken);
|
|
112
|
+
};
|
|
113
|
+
socket.once('connect', () => settle(true));
|
|
114
|
+
socket.once('error', () => settle(false));
|
|
115
|
+
socket.setTimeout(750, () => settle(false));
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function waitForPort(
|
|
120
|
+
port: number,
|
|
121
|
+
what: string,
|
|
122
|
+
child: ChildProcess,
|
|
123
|
+
timeoutMs: number,
|
|
124
|
+
): Promise<void> {
|
|
125
|
+
const deadline = Date.now() + timeoutMs;
|
|
126
|
+
for (;;) {
|
|
127
|
+
if (await portTaken(port)) return;
|
|
128
|
+
if (child.exitCode !== null) {
|
|
129
|
+
throw new Error(`${what} exited (code ${child.exitCode}) before it listened on ${port}.`);
|
|
130
|
+
}
|
|
131
|
+
if (Date.now() > deadline) {
|
|
132
|
+
throw new Error(`${what} never listened on ${port} within ${Math.round(timeoutMs / 1000)}s.`);
|
|
133
|
+
}
|
|
134
|
+
await new Promise((settle) => setTimeout(settle, 500));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Start the workbench for this session: the REH, then the proxy in front of it
|
|
140
|
+
* and of this process.
|
|
141
|
+
*
|
|
142
|
+
* The argv is the same string whichever kind the workbench is — a release is
|
|
143
|
+
* meant to be measured against the sources, and a boot that differed in a flag
|
|
144
|
+
* would be measuring the flag.
|
|
145
|
+
*/
|
|
146
|
+
export async function startFrameWorkbench(options: {
|
|
147
|
+
launch: FrameLaunch;
|
|
148
|
+
projectRoot: string;
|
|
149
|
+
sessionPort: number;
|
|
150
|
+
/**
|
|
151
|
+
* EXTRA ENVIRONMENT FOR THE REH, and through it for its extension host.
|
|
152
|
+
* Today that is the Chat view's runtime handoff (`frontend-handoff.ts`): the
|
|
153
|
+
* bundled supercode frontend reads `SUPERCODE_FRONTEND_*` at activation. It is
|
|
154
|
+
* a SPAWN argument and not a later call because a child's environment cannot
|
|
155
|
+
* be changed after it starts — which is why the session starts its harness
|
|
156
|
+
* runtime before it gets here, and why there is deliberately no
|
|
157
|
+
* restart-the-REH path when one arrives late.
|
|
158
|
+
*/
|
|
159
|
+
env?: Readonly<Record<string, string>>;
|
|
160
|
+
log: (line: string) => void;
|
|
161
|
+
}): Promise<FrameWorkbench> {
|
|
162
|
+
const { launch, projectRoot, sessionPort, log } = options;
|
|
163
|
+
// A WORKBENCH IS ONE PRODUCT'S (P3): the editor kit and one product's
|
|
164
|
+
// workbench half are overlaid on the fork together, so a release or checkout
|
|
165
|
+
// built for the other product is refused here BY NAME. The session is the
|
|
166
|
+
// right place for it — the CLI checks the same pair before a server exists,
|
|
167
|
+
// and this is the read that spawns. A project whose product cannot be
|
|
168
|
+
// resolved is not judged: `/__editor/served-modules` is the door that says
|
|
169
|
+
// why, in its own words.
|
|
170
|
+
const product = sessionProduct(projectRoot);
|
|
171
|
+
const workbench = resolveWorkbench(
|
|
172
|
+
launch.workbenchDir,
|
|
173
|
+
product === null ? undefined : workbenchProductId(product.name),
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
for (const [port, what] of [
|
|
177
|
+
[launch.rehPort, 'the Code-OSS server'],
|
|
178
|
+
[launch.proxyPort, 'the one-origin proxy'],
|
|
179
|
+
] as const) {
|
|
180
|
+
if (await portTaken(port)) {
|
|
181
|
+
throw new Error(
|
|
182
|
+
`This project reserves port ${port} for ${what}, and something is already listening there. ` +
|
|
183
|
+
`Free it (\`lsof -nP -iTCP:${port} -sTCP:LISTEN\`) — the frame never drifts to another port.`,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
log(
|
|
189
|
+
`frame: Code-OSS ${workbench.kind} ${workbench.commit.slice(0, 12)} (${workbench.dir}) on ${launch.rehPort}`,
|
|
190
|
+
);
|
|
191
|
+
const reh = spawn(
|
|
192
|
+
workbench.serverBin,
|
|
193
|
+
[
|
|
194
|
+
'--host',
|
|
195
|
+
'127.0.0.1',
|
|
196
|
+
'--port',
|
|
197
|
+
String(launch.rehPort),
|
|
198
|
+
'--without-connection-token',
|
|
199
|
+
projectRoot,
|
|
200
|
+
],
|
|
201
|
+
{
|
|
202
|
+
cwd: workbench.cwd,
|
|
203
|
+
stdio: 'ignore',
|
|
204
|
+
detached: true,
|
|
205
|
+
env: { ...process.env, ...options.env },
|
|
206
|
+
},
|
|
207
|
+
);
|
|
208
|
+
let proxy: { close(): Promise<void> } | null = null;
|
|
209
|
+
const closeProxy = async (): Promise<void> => {
|
|
210
|
+
const closing = proxy?.close() ?? Promise.resolve();
|
|
211
|
+
proxy = null;
|
|
212
|
+
await closing;
|
|
213
|
+
};
|
|
214
|
+
// 2 s between SIGTERM and SIGKILL, not `stopProcess`'s 5 s default: this
|
|
215
|
+
// runs as ONE TASK of the session's shutdown list, which bounds each task at
|
|
216
|
+
// 4 s so the whole shutdown fits inside `vgai close`'s 5.5 s grace. The
|
|
217
|
+
// escalation must COMPLETE inside that window — the REH is detached into its
|
|
218
|
+
// own process group, so the group SIGKILL `vgai close` sends at 5.5 s never
|
|
219
|
+
// reaches it, and a REH that outlives this process is an orphan on the
|
|
220
|
+
// reserved `frame` port that refuses the next `vgai edit` by name (measured
|
|
221
|
+
// 2026-09-21 under load average ~30).
|
|
222
|
+
const stopServer = (): Promise<void> => stopProcess(reh, 2_000);
|
|
223
|
+
const stop = async (): Promise<void> => {
|
|
224
|
+
await Promise.all([closeProxy(), stopServer()]);
|
|
225
|
+
};
|
|
226
|
+
try {
|
|
227
|
+
await waitForPort(launch.rehPort, 'the Code-OSS server', reh, 300_000);
|
|
228
|
+
log(
|
|
229
|
+
`frame: one-origin proxy on ${launch.proxyPort} → workbench ${launch.rehPort} + session ${sessionPort}`,
|
|
230
|
+
);
|
|
231
|
+
const started = await startFrameProxy({
|
|
232
|
+
port: launch.proxyPort,
|
|
233
|
+
upstreamPort: launch.rehPort,
|
|
234
|
+
sessionPort,
|
|
235
|
+
projectRoot,
|
|
236
|
+
// WHICH WAY ROUND THE PAGE PAINTS, from the product resolved above —
|
|
237
|
+
// the same read that decides which workbench may spawn decides the
|
|
238
|
+
// workbench's first frame, so there is one resolution and not two.
|
|
239
|
+
colorTheme: product?.colorTheme ?? null,
|
|
240
|
+
log,
|
|
241
|
+
});
|
|
242
|
+
proxy = started;
|
|
243
|
+
return {
|
|
244
|
+
identity: {
|
|
245
|
+
kind: workbench.kind,
|
|
246
|
+
dir: workbench.dir,
|
|
247
|
+
commit: workbench.commit,
|
|
248
|
+
product: workbench.product,
|
|
249
|
+
},
|
|
250
|
+
url: started.url,
|
|
251
|
+
stopServer,
|
|
252
|
+
closeProxy,
|
|
253
|
+
stop,
|
|
254
|
+
};
|
|
255
|
+
} catch (error) {
|
|
256
|
+
await stop();
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE AI IN THE TAB GETS ITS RUNTIME FROM THE SESSION, AT SPAWN.
|
|
3
|
+
*
|
|
4
|
+
* ARCHITECTURE-CORE §The core is Code-OSS, rule 7: the agent's front end is the
|
|
5
|
+
* workbench's own Chat view, filled by `sdk/frontend-vscode`, and its back end is
|
|
6
|
+
* the harness runtime this session already runs. This module is the wire between
|
|
7
|
+
* them, and it is four environment variables.
|
|
8
|
+
*
|
|
9
|
+
* WHY ENV, AND WHY AT SPAWN. The extension's second connection path (its README,
|
|
10
|
+
* "The runtime's environment handover") reads `SUPERCODE_FRONTEND_URL`,
|
|
11
|
+
* `_CLIENT_ID`, `_CREDENTIAL_FILE` and `_PERMISSIONS` from the EXTENSION HOST's
|
|
12
|
+
* environment at activation — the same shape supercode's own CLI uses to launch
|
|
13
|
+
* the pi frontend, without the `PI` infix. A Code-OSS server passes its
|
|
14
|
+
* environment to its extension host, and `frame-workbench.ts` spawns that server,
|
|
15
|
+
* so the handover costs no pasted token and no route of ours. The price is that
|
|
16
|
+
* env is FIXED AT SPAWN: whatever the runtime is when the REH starts is what the
|
|
17
|
+
* panel gets, which is why the session starts the runtime first.
|
|
18
|
+
*
|
|
19
|
+
* WHY THE SESSION MINTS RATHER THAN FORWARDS. The runtime's receipt carries a
|
|
20
|
+
* BOOTSTRAP bearer (`crates/harness/src/live_runtime.rs`), and handing that to a
|
|
21
|
+
* frontend would give it the runtime's own authority. Every supercode frontend
|
|
22
|
+
* instead asks the runtime's loopback mint door for a credential scoped to its
|
|
23
|
+
* own client id and grant, and gives it back on the way out. That door's reader
|
|
24
|
+
* and caller are supercode's, not ours —
|
|
25
|
+
* `@volter-ai-dev/supercode-harness-sdk/live-runtime`, extracted there from
|
|
26
|
+
* `sdk/teams`'s HTTP door when this became its second consumer.
|
|
27
|
+
*
|
|
28
|
+
* WHAT THE SESSION NEVER DOES is read the credential file back. It receives 64
|
|
29
|
+
* hex bytes from the mint door, writes them 0600 where only this user can read
|
|
30
|
+
* them, and hands over the PATH; the extension re-checks the file's identity
|
|
31
|
+
* across the open (`sdk/frontend-vscode`'s `credential.ts`).
|
|
32
|
+
*
|
|
33
|
+
* RESOURCE OWNERSHIP, stated once:
|
|
34
|
+
* - OWNER: the `HarnessChatService` that minted it. It holds exactly one
|
|
35
|
+
* handoff at a time and replaces it only by disposing the previous one.
|
|
36
|
+
* - SHARERS: the REH child, which received the path in its environment and may
|
|
37
|
+
* re-read it across an extension-host reload for as long as the session lives.
|
|
38
|
+
* - THE ONE TEARDOWN: `dispose()`, called from the service's `close()` — the
|
|
39
|
+
* same shutdown list that stops the REH. Nothing else may revoke it, because
|
|
40
|
+
* a revoked grant with a live panel is a chat that has silently gone deaf.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import { randomUUID } from 'node:crypto';
|
|
44
|
+
import { chmodSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
45
|
+
import { dirname, join, resolve } from 'node:path';
|
|
46
|
+
import { pathToFileURL } from 'node:url';
|
|
47
|
+
|
|
48
|
+
/** `observe` watches, `interact` sends, `approve` answers a permission request.
|
|
49
|
+
* `terminate` is deliberately NOT here: the panel may drive the agent and answer
|
|
50
|
+
* for it, and may not kill the session the terminal and the CLI also hold. */
|
|
51
|
+
export const FRONTEND_PERMISSIONS = 'observe,interact,approve';
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* THE OTHER HALF OF THE HANDOVER: why there is no runtime, when there is none.
|
|
55
|
+
*
|
|
56
|
+
* The four `SUPERCODE_FRONTEND_*` variables above hand the extension a runtime. This one hands
|
|
57
|
+
* it the SENTENCE instead — B9c's refusal, which names the harness and its own login command —
|
|
58
|
+
* and `sdk/frontend-vscode` 0.1.3 reads it at activation and shows it as the session's first
|
|
59
|
+
* turn. Without it the Chat view was indistinguishable from a working one: "Build with Agent"
|
|
60
|
+
* and a live input over an agent that would never answer (measured on the 0.1.1 bytes, gate 6).
|
|
61
|
+
*
|
|
62
|
+
* It is never set beside the four: a handoff either carries a runtime or carries the reason it
|
|
63
|
+
* does not.
|
|
64
|
+
*/
|
|
65
|
+
export const FRONTEND_UNAVAILABLE_ENV = 'SUPERCODE_FRONTEND_UNAVAILABLE';
|
|
66
|
+
|
|
67
|
+
/** The four variables, and the one call that ends the grant they carry. */
|
|
68
|
+
export interface FrontendHandoff {
|
|
69
|
+
/** Spread into the REH spawn's environment. Empty means there is nothing to hand over. */
|
|
70
|
+
readonly env: Readonly<Record<string, string>>;
|
|
71
|
+
/** The client id the runtime's lease coordinator will see. */
|
|
72
|
+
readonly clientId: string;
|
|
73
|
+
/** True when the runtime's mint door answered; false when it 404'd and the receipt's own
|
|
74
|
+
* bearer was handed over instead (see the measurement in `mintFrontendHandoff`). */
|
|
75
|
+
readonly minted: boolean;
|
|
76
|
+
/** Revoke the grant and delete the credential file. Idempotent. */
|
|
77
|
+
dispose(): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface LiveRuntimeReceipt {
|
|
81
|
+
readonly base_url: string;
|
|
82
|
+
readonly token: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface LiveRuntimeDoor {
|
|
86
|
+
findLiveReceipt(runtimeId: string, env?: NodeJS.ProcessEnv): LiveRuntimeReceipt | null;
|
|
87
|
+
mintFrontendCredential(
|
|
88
|
+
receipt: LiveRuntimeReceipt,
|
|
89
|
+
options: { clientId: string; grant: 'interactive' | 'observer' },
|
|
90
|
+
): Promise<string>;
|
|
91
|
+
revokeFrontendCredential(
|
|
92
|
+
receipt: LiveRuntimeReceipt,
|
|
93
|
+
options: { clientId: string },
|
|
94
|
+
): Promise<number | undefined>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function moduleCandidate(root: string | undefined, file: string): string[] {
|
|
98
|
+
if (!root) return [];
|
|
99
|
+
return [root.endsWith('.mjs') ? root : join(root, file)];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The supercode door, resolved the way every other optional supercode import in
|
|
104
|
+
* this server is: the published package first, a sibling checkout after, and a
|
|
105
|
+
* refusal that names every location tried rather than an opaque `ERR_MODULE_NOT_FOUND`.
|
|
106
|
+
*/
|
|
107
|
+
async function importLiveRuntimeDoor(engineRoot: string): Promise<LiveRuntimeDoor> {
|
|
108
|
+
const sibling = join(dirname(engineRoot), 'supercode', 'sdk', 'typescript', 'live-runtime.mjs');
|
|
109
|
+
const cwdSibling = join(
|
|
110
|
+
dirname(resolve(process.cwd())),
|
|
111
|
+
'supercode',
|
|
112
|
+
'sdk',
|
|
113
|
+
'typescript',
|
|
114
|
+
'live-runtime.mjs',
|
|
115
|
+
);
|
|
116
|
+
const failures: string[] = [];
|
|
117
|
+
for (const candidate of [
|
|
118
|
+
...moduleCandidate(process.env['SUPERCODE_SDK_PATH'], 'live-runtime.mjs'),
|
|
119
|
+
'@volter-ai-dev/supercode-harness-sdk/live-runtime',
|
|
120
|
+
sibling,
|
|
121
|
+
cwdSibling,
|
|
122
|
+
]) {
|
|
123
|
+
try {
|
|
124
|
+
const specifier = candidate.startsWith('/') ? pathToFileURL(candidate).href : candidate;
|
|
125
|
+
const module = (await import(specifier)) as Partial<LiveRuntimeDoor>;
|
|
126
|
+
if (module.findLiveReceipt && module.mintFrontendCredential && module.revokeFrontendCredential) {
|
|
127
|
+
return module as LiveRuntimeDoor;
|
|
128
|
+
}
|
|
129
|
+
failures.push(`${candidate}: missing findLiveReceipt/mintFrontendCredential/revokeFrontendCredential`);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
failures.push(`${candidate}: ${error instanceof Error ? error.message : String(error)}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
throw new Error(
|
|
135
|
+
`The supercode live-runtime door could not be loaded, so the Chat view has no runtime to attach to. Tried:\n ${failures.join('\n ')}`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Mint one scoped credential for a runtime this session started, and return the
|
|
141
|
+
* environment the extension host reads at activation.
|
|
142
|
+
*
|
|
143
|
+
* `runtimeSessionId` is `ManagedRuntime.handle.runtime_id` — the same string the
|
|
144
|
+
* runtime wrote into its receipt as `runtime_session_id`.
|
|
145
|
+
*/
|
|
146
|
+
export async function mintFrontendHandoff(options: {
|
|
147
|
+
readonly engineRoot: string;
|
|
148
|
+
readonly runtimeSessionId: string;
|
|
149
|
+
/** Where the 0600 credential goes. One directory per session, removed with it. */
|
|
150
|
+
readonly directory: string;
|
|
151
|
+
}): Promise<FrontendHandoff> {
|
|
152
|
+
const door = await importLiveRuntimeDoor(options.engineRoot);
|
|
153
|
+
const receipt = door.findLiveReceipt(options.runtimeSessionId);
|
|
154
|
+
if (!receipt) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Supercode registered no live receipt for runtime ${options.runtimeSessionId}, so there is nothing for the Chat view to attach to.`,
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
const clientId = `vgai-editor-${process.pid}-${randomUUID().slice(0, 8)}`;
|
|
160
|
+
// THERE ARE TWO HTTP SERVERS IN A SUPERCODE RUNTIME, and a MANAGED runtime's receipt
|
|
161
|
+
// points at the one WITHOUT the mint door. Measured against supercode 0.4.36 on
|
|
162
|
+
// 2026-09-21, on a runtime started through `startManagedRuntime`:
|
|
163
|
+
//
|
|
164
|
+
// POST /rpc 200 (frontend.v2.describe answered)
|
|
165
|
+
// POST /_supercode/frontend-credentials/mint 404 {"error":"not found"}
|
|
166
|
+
// …the same path with no bearer 401 — so it IS supercode's server
|
|
167
|
+
//
|
|
168
|
+
// `crates/harness/src/server.rs`: `handle_http_conn` (~:2611) serves the mint door and is
|
|
169
|
+
// what `supercode serve` runs; `handle_frontend_http_conn` (~:2962) is what
|
|
170
|
+
// `insert_hosted_runtime` starts and registers in the receipt, and it serves `POST /rpc`,
|
|
171
|
+
// `GET /frontend/events` and the observer assets — everything else is that 404.
|
|
172
|
+
//
|
|
173
|
+
// So the credential is minted WHEN THE DOOR EXISTS and is the receipt's own bearer when it
|
|
174
|
+
// does not. That is not an invention: it is supercode's own fallback, transcribed from
|
|
175
|
+
// `sdk/teams`'s HTTP door (`if (!/^mint 404/.test(error.message)) throw error;`), and it is
|
|
176
|
+
// still SCOPED — the generated frontend client sends `x-supercode-client-id` and
|
|
177
|
+
// `x-supercode-permissions` on every request (`sdk/frontend/client.mjs` :104-105), and
|
|
178
|
+
// `coordinated_http_client` (~:2491) takes the supplied id for an unbound credential and
|
|
179
|
+
// RESTRICTS the authorization to the header's permissions. What the fallback loses is the
|
|
180
|
+
// server-side BINDING: a client that stripped those headers would keep the bootstrap's
|
|
181
|
+
// authorization. Serving the mint door on the frontend server is supercode's to add.
|
|
182
|
+
let token: string;
|
|
183
|
+
let minted: boolean;
|
|
184
|
+
try {
|
|
185
|
+
token = await door.mintFrontendCredential(receipt, { clientId, grant: 'interactive' });
|
|
186
|
+
minted = true;
|
|
187
|
+
} catch (error) {
|
|
188
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
189
|
+
if (!/^mint 404/.test(message)) throw error;
|
|
190
|
+
token = receipt.token;
|
|
191
|
+
minted = false;
|
|
192
|
+
}
|
|
193
|
+
// The reader's own rules (`sdk/frontend-vscode`'s `credential.ts`): a regular,
|
|
194
|
+
// private, single-linked file of exactly 64 lowercase hex bytes. Checked HERE too,
|
|
195
|
+
// because a malformed secret should name the door it came from rather than surface later
|
|
196
|
+
// as "the credential is malformed" from inside an extension host with no logs a person reads.
|
|
197
|
+
if (!/^[0-9a-f]{64}$/.test(token)) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
`The runtime's ${minted ? 'mint door' : 'receipt'} carried ${token.length} bytes that are not 64 hex characters; the Chat view's credential reader would refuse them.`,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
mkdirSync(options.directory, { recursive: true, mode: 0o700 });
|
|
203
|
+
chmodSync(options.directory, 0o700);
|
|
204
|
+
const credentialFile = join(options.directory, 'frontend-credential');
|
|
205
|
+
// `mode` on `writeFileSync` is masked by the umask, so the chmod is not redundant:
|
|
206
|
+
// a 0022 umask would leave 0644 and the extension refuses a world-readable credential.
|
|
207
|
+
writeFileSync(credentialFile, token, { mode: 0o600 });
|
|
208
|
+
chmodSync(credentialFile, 0o600);
|
|
209
|
+
let disposed = false;
|
|
210
|
+
return {
|
|
211
|
+
env: {
|
|
212
|
+
SUPERCODE_FRONTEND_URL: receipt.base_url,
|
|
213
|
+
SUPERCODE_FRONTEND_CLIENT_ID: clientId,
|
|
214
|
+
SUPERCODE_FRONTEND_CREDENTIAL_FILE: credentialFile,
|
|
215
|
+
SUPERCODE_FRONTEND_PERMISSIONS: FRONTEND_PERMISSIONS,
|
|
216
|
+
},
|
|
217
|
+
clientId,
|
|
218
|
+
minted,
|
|
219
|
+
async dispose() {
|
|
220
|
+
if (disposed) return;
|
|
221
|
+
disposed = true;
|
|
222
|
+
rmSync(options.directory, { recursive: true, force: true });
|
|
223
|
+
// Only a MINTED grant is ours to give back; the receipt's own bearer is the runtime's
|
|
224
|
+
// and dies with it. A runtime that has already exited cannot take anything back either,
|
|
225
|
+
// and saying so would be reporting the shutdown we are already performing.
|
|
226
|
+
if (minted) await door.revokeFrontendCredential(receipt, { clientId }).catch(() => undefined);
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure predicate for the `vgai-game-globals` Vite plugin in `dev.ts` — split
|
|
3
|
+
* out into its own side-effect-free module so it's unit-testable without
|
|
4
|
+
* booting Vite/Express (`dev.ts`'s module top-level calls `main()`, which
|
|
5
|
+
* starts real servers — importing it directly in a test would do that).
|
|
6
|
+
*
|
|
7
|
+
* The prelude used to be scoped to `projectRoots` alone (an opened project's
|
|
8
|
+
* own `/src/`), which covers first-party project code and play-mode's game
|
|
9
|
+
* examples but NOT the in-tree ingest fixtures' same-realm
|
|
10
|
+
* ingest-fixture entry modules — those live under this EDITOR
|
|
11
|
+
* PACKAGE's own `packages/editor/src/ingest/games/**` tree (every surface —
|
|
12
|
+
* holds the former `games-2d`/`games-react` siblings),
|
|
13
|
+
* which `ingest/registry.ts` pulls into the SAME Vite module graph via
|
|
14
|
+
* `import.meta.glob` (they are ordinary `/src/` modules Vite already knows
|
|
15
|
+
* about statically — not an external project folder), so they were served
|
|
16
|
+
* UNSHADOWED: a vendored game's raw `window`/`document` input listeners ran
|
|
17
|
+
* for its entire mount regardless of editor focus.
|
|
18
|
+
*/
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
import { isEditorLanePath } from '@volter/editor-sdk/session/tool-contribution-convention';
|
|
21
|
+
import { isPathInside } from './server-utils';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The same-realm ingest-fixture root, given this editor package's own `src/`
|
|
25
|
+
* directory. Fixed (not runtime-discovered) — this folder is part of THIS
|
|
26
|
+
* package's source tree, not a project a user opens. It was a LIST of two
|
|
27
|
+
* once the per-library fixture directories merged into one; the
|
|
28
|
+
* signature stays plural because the caller wires an array of roots and
|
|
29
|
+
* nothing is gained by narrowing it.
|
|
30
|
+
*/
|
|
31
|
+
export function ingestGameShadowRoots(editorSrcRoot: string): string[] {
|
|
32
|
+
return [
|
|
33
|
+
path.resolve(editorSrcRoot, 'ingest/games'),
|
|
34
|
+
// THE GAME'S OWN SOURCE, which until now was the half that got missed.
|
|
35
|
+
// The root above covers only the host-authored manifest folder — the
|
|
36
|
+
// entry shim, a contract shim — while every line of the game itself lives
|
|
37
|
+
// under `vendor/games/<id>/src/`, outside it. A source-vendored game
|
|
38
|
+
// therefore ran its raw `window`/`document` listeners and its own rAF
|
|
39
|
+
// loop UNSHADOWED for its entire mount, so play-mode's input gate and
|
|
40
|
+
// pause reached nothing in it. Measured on the racing-game ingest, whose
|
|
41
|
+
// `controls/Keyboard.ts` binds `window.addEventListener('keydown')`
|
|
42
|
+
// directly and whose Vehicle drives a `useFrame` loop: with only the
|
|
43
|
+
// manifest folder shadowed, `editor.pause()` left the coverage `loop` row
|
|
44
|
+
// at `loop: null` — the host held no gate over it.
|
|
45
|
+
//
|
|
46
|
+
// Bundle-vendored games are deliberately NOT covered: they are BUILT
|
|
47
|
+
// output under `public/ingest/<id>/`, which `isShadowableModulePath`
|
|
48
|
+
// already declines (no `/src/` segment) and which the prelude's lexical
|
|
49
|
+
// shadow is not safe to prepend to anyway.
|
|
50
|
+
path.resolve(editorSrcRoot, '../../../vendor/games'),
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* True if `file` is a `/src/` TS/JS module — the shape the prelude assumes
|
|
56
|
+
* (a lexically-scoped `const window=…,document=…;` prepended to the top of
|
|
57
|
+
* the module body; see `gated-globals.ts`'s doc comment for why that's safe
|
|
58
|
+
* even ahead of the module's own `import` statements).
|
|
59
|
+
*
|
|
60
|
+
* DEPENDENCY CODE IS NEVER THE PROJECT'S OWN, and the `/src/` test alone does
|
|
61
|
+
* not say so: a project whose own path contains a `src` segment makes every
|
|
62
|
+
* file under its `node_modules/` match — including Vite's project-local
|
|
63
|
+
* optimized-deps cache (`<project>/node_modules/.vite-editor/deps/three.js`,
|
|
64
|
+
* `editorViteCacheDir`). Measured on an ingest whose manifest folder lives
|
|
65
|
+
* under `packages/editor/src/ingest/games/`: the prebundled
|
|
66
|
+
* `three.js` was instrumented by `vite-plugin-creation-site`, so
|
|
67
|
+
* `DRACOLoader`'s worker — which it builds by `DRACOWorker.toString()` and
|
|
68
|
+
* hands to a Blob URL — carried the recorder identifier into a realm that has
|
|
69
|
+
* no such binding. `__vgaiCS$ is not defined` in a `blob:` URL, every Draco
|
|
70
|
+
* mesh failed to decode, `useGLTF` suspended forever, and the scene mounted
|
|
71
|
+
* EMPTY with no error naming any of it. Ordinary projects were safe only by
|
|
72
|
+
* accident of their path.
|
|
73
|
+
*/
|
|
74
|
+
export function isShadowableModulePath(file: string): boolean {
|
|
75
|
+
if (file.includes('/node_modules/') || isEditorLanePath(file)) return false;
|
|
76
|
+
return /\.(ts|tsx|js|jsx)$/.test(file) && file.includes('/src/');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* True if `file` should get the `GAME_GLOBALS_PRELUDE` shadow prepended:
|
|
81
|
+
* a shadowable module path under any of `roots` (an opened project's root,
|
|
82
|
+
* or one of {@link ingestGameShadowRoots}).
|
|
83
|
+
*/
|
|
84
|
+
export function shouldShadowGameGlobals(file: string, roots: Iterable<string>): boolean {
|
|
85
|
+
if (!isShadowableModulePath(file)) return false;
|
|
86
|
+
// Containment, not a string prefix: a bare `startsWith` shadows every module
|
|
87
|
+
// of the SIBLING project `<root>-old/src/…` as if it belonged to `<root>`.
|
|
88
|
+
for (const root of roots) {
|
|
89
|
+
if (isPathInside(root, file)) return true;
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** A project (or ingest-fixture) stylesheet, not a dependency. */
|
|
95
|
+
export function isGameCssPath(file: string): boolean {
|
|
96
|
+
return file.endsWith('.css') && !file.includes('/node_modules/') && !isEditorLanePath(file);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* True if Vite-imported game CSS must be rewritten into `@scope` so
|
|
101
|
+
* `html`/`body`/`*` rules cannot restyle the editor document. The sibling
|
|
102
|
+
* of {@link shouldShadowGameGlobals} for stylesheets: first-party worlds
|
|
103
|
+
* `import './style.css'`, which Vite injects as a page sheet unless this
|
|
104
|
+
* transform contains it the same way `server/scoped-game-css.ts` contains
|
|
105
|
+
* a declared ingest stylesheet.
|
|
106
|
+
*/
|
|
107
|
+
export function shouldScopeGameCss(file: string, roots: Iterable<string>): boolean {
|
|
108
|
+
if (!isGameCssPath(file)) return false;
|
|
109
|
+
for (const root of roots) {
|
|
110
|
+
if (isPathInside(root, file)) return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|