@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,123 @@
|
|
|
1
|
+
import { type ChildProcess, spawn } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
export type ShareTunnelProvider = 'cloudflared' | 'ngrok';
|
|
4
|
+
|
|
5
|
+
export interface ShareTunnel {
|
|
6
|
+
child: ChildProcess;
|
|
7
|
+
publicUrl: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ShareTunnelStarter = (port: number) => Promise<ShareTunnel>;
|
|
11
|
+
|
|
12
|
+
function publicUrl(line: string, pattern: RegExp): string | null {
|
|
13
|
+
const direct = line.match(pattern)?.[0];
|
|
14
|
+
if (direct) return direct;
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(line) as Record<string, unknown>;
|
|
17
|
+
for (const value of Object.values(parsed)) {
|
|
18
|
+
if (typeof value !== 'string') continue;
|
|
19
|
+
const match = value.match(pattern)?.[0];
|
|
20
|
+
if (match) return match;
|
|
21
|
+
}
|
|
22
|
+
} catch {
|
|
23
|
+
// Human-readable output is handled by the direct expression.
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function parseNgrokPublicUrl(line: string): string | null {
|
|
29
|
+
return publicUrl(line, /https:\/\/[a-zA-Z0-9.-]+\.ngrok(?:-free)?\.(?:app|dev)/);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function parseCloudflaredPublicUrl(line: string): string | null {
|
|
33
|
+
return publicUrl(line, /https:\/\/[a-zA-Z0-9-]+\.trycloudflare\.com/);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function startTunnelProcess(input: {
|
|
37
|
+
provider: ShareTunnelProvider;
|
|
38
|
+
command: string;
|
|
39
|
+
args: string[];
|
|
40
|
+
parseUrl(line: string): string | null;
|
|
41
|
+
prerequisite: string;
|
|
42
|
+
}): Promise<ShareTunnel> {
|
|
43
|
+
const child = spawn(input.command, input.args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
44
|
+
return new Promise<ShareTunnel>((resolveUrl, rejectUrl) => {
|
|
45
|
+
let settled = false;
|
|
46
|
+
let output = '';
|
|
47
|
+
const timer = setTimeout(() => {
|
|
48
|
+
if (settled) return;
|
|
49
|
+
settled = true;
|
|
50
|
+
child.kill('SIGTERM');
|
|
51
|
+
rejectUrl(
|
|
52
|
+
new Error(`${input.provider} did not publish a URL within 30 seconds.\n${output.trim()}`),
|
|
53
|
+
);
|
|
54
|
+
}, 30_000);
|
|
55
|
+
const inspect = (chunk: Buffer | string) => {
|
|
56
|
+
const text = chunk.toString();
|
|
57
|
+
output = `${output}${text}`.slice(-8_000);
|
|
58
|
+
for (const line of text.split(/\r?\n/)) {
|
|
59
|
+
const url = input.parseUrl(line);
|
|
60
|
+
if (!url || settled) continue;
|
|
61
|
+
settled = true;
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
resolveUrl({ child, publicUrl: url });
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
child.stdout?.on('data', inspect);
|
|
68
|
+
child.stderr?.on('data', inspect);
|
|
69
|
+
child.once('error', (error) => {
|
|
70
|
+
if (settled) return;
|
|
71
|
+
settled = true;
|
|
72
|
+
clearTimeout(timer);
|
|
73
|
+
rejectUrl(new Error(error.message.includes('ENOENT') ? input.prerequisite : error.message));
|
|
74
|
+
});
|
|
75
|
+
child.once('exit', (code) => {
|
|
76
|
+
if (settled) return;
|
|
77
|
+
settled = true;
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
rejectUrl(
|
|
80
|
+
new Error(
|
|
81
|
+
`${input.provider} exited before publishing a URL (code ${code}).\n${output.trim()}`,
|
|
82
|
+
),
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function startNgrokShareTunnel(port: number): Promise<ShareTunnel> {
|
|
89
|
+
return startTunnelProcess({
|
|
90
|
+
provider: 'ngrok',
|
|
91
|
+
command: 'ngrok',
|
|
92
|
+
args: ['http', `http://127.0.0.1:${port}`, '--log', 'stdout', '--log-format', 'json'],
|
|
93
|
+
parseUrl: parseNgrokPublicUrl,
|
|
94
|
+
prerequisite: 'ngrok is required for this share. Install and authenticate ngrok first.',
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function startCloudflaredShareTunnel(port: number): Promise<ShareTunnel> {
|
|
99
|
+
return startTunnelProcess({
|
|
100
|
+
provider: 'cloudflared',
|
|
101
|
+
command: 'cloudflared',
|
|
102
|
+
args: [
|
|
103
|
+
'tunnel',
|
|
104
|
+
'--url',
|
|
105
|
+
`http://127.0.0.1:${port}`,
|
|
106
|
+
'--no-autoupdate',
|
|
107
|
+
// Quick Tunnels default to QUIC, which is commonly blocked on managed
|
|
108
|
+
// networks even when ordinary HTTPS works. HTTP/2 preserves the
|
|
109
|
+
// accountless path without requiring UDP egress.
|
|
110
|
+
'--protocol',
|
|
111
|
+
'http2',
|
|
112
|
+
'--config',
|
|
113
|
+
process.platform === 'win32' ? 'NUL' : '/dev/null',
|
|
114
|
+
],
|
|
115
|
+
parseUrl: parseCloudflaredPublicUrl,
|
|
116
|
+
prerequisite:
|
|
117
|
+
'cloudflared is required for this share. Install cloudflared; Quick Tunnels need no Cloudflare account.',
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function shareTunnelStarter(provider: ShareTunnelProvider): ShareTunnelStarter {
|
|
122
|
+
return provider === 'cloudflared' ? startCloudflaredShareTunnel : startNgrokShareTunnel;
|
|
123
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort launch of an OS "open a URL" command (`open`, `cmd /c start`,
|
|
3
|
+
* `powershell.exe Start-Process`, `xdg-open`, …), extracted from
|
|
4
|
+
* `index.ts`'s `openBrowser` into its own module so it's unit-testable
|
|
5
|
+
* against a REAL spawned child (see `spawn-opener.test.ts`) without pulling
|
|
6
|
+
* in the whole CLI entry point.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { type ChildProcess, spawn } from 'node:child_process';
|
|
10
|
+
|
|
11
|
+
/** Cap on how much of a failed opener's stderr we buffer before printing —
|
|
12
|
+
* enough for a real error message, small enough to never matter for a
|
|
13
|
+
* detached fire-and-forget child. */
|
|
14
|
+
export const OPENER_STDERR_CAP_BYTES = 2048;
|
|
15
|
+
|
|
16
|
+
/** An unref'd child's piped stderr only stays readable for as long as THIS
|
|
17
|
+
* process's event loop keeps ticking — normally guaranteed by the caller's
|
|
18
|
+
* verified-open poll (>=15s, see waitForVerifiedEditorOpen). Belt-and-
|
|
19
|
+
* suspenders bound so a genuinely long-lived/never-exiting opener can't
|
|
20
|
+
* hold the pipe (and this process) open indefinitely if the parent exits
|
|
21
|
+
* on its own first. */
|
|
22
|
+
export const OPENER_EXIT_WATCH_TIMEOUT_MS = 20_000;
|
|
23
|
+
|
|
24
|
+
/** Fire one open attempt, NAMING the failure instead of swallowing it.
|
|
25
|
+
* Two failure modes, both silent before this fix:
|
|
26
|
+
* - meteor-dodge dry-run friction #1: the powershell.exe hand-off died
|
|
27
|
+
* silently in a background shell — spawn launch failures arrive on the
|
|
28
|
+
* child's 'error' event, which nothing listened to.
|
|
29
|
+
* - run-3 dogfood friction #3: a child that LAUNCHES but exits nonzero
|
|
30
|
+
* (e.g. Start-Process itself failing inside powershell) was silent too —
|
|
31
|
+
* stdio was fully 'ignore'd and nothing checked the exit code.
|
|
32
|
+
* Still best-effort: a failure logs one line (stderr captured, capped, and
|
|
33
|
+
* included when available) and runs `fallback`, if given — never throws,
|
|
34
|
+
* never blocks. */
|
|
35
|
+
export function spawnOpener(cmd: string, cmdArgs: string[], fallback?: () => void): void {
|
|
36
|
+
let child: ChildProcess;
|
|
37
|
+
try {
|
|
38
|
+
child = spawn(cmd, cmdArgs, { stdio: ['ignore', 'ignore', 'pipe'], detached: true });
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error(`vgai: auto-open via ${cmd} failed: ${(err as Error).message}`);
|
|
41
|
+
fallback?.();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const stderrChunks: Buffer[] = [];
|
|
46
|
+
let stderrBytes = 0;
|
|
47
|
+
child.stderr?.on('data', (chunk: Buffer) => {
|
|
48
|
+
if (stderrBytes >= OPENER_STDERR_CAP_BYTES) return;
|
|
49
|
+
const remaining = OPENER_STDERR_CAP_BYTES - stderrBytes;
|
|
50
|
+
const slice = chunk.length > remaining ? chunk.subarray(0, remaining) : chunk;
|
|
51
|
+
stderrChunks.push(slice);
|
|
52
|
+
stderrBytes += slice.length;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
child.on('error', (err) => {
|
|
56
|
+
console.error(`vgai: auto-open via ${cmd} failed to launch: ${err.message}`);
|
|
57
|
+
fallback?.();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
child.on('exit', (code) => {
|
|
61
|
+
if (code !== null && code !== 0) {
|
|
62
|
+
const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();
|
|
63
|
+
console.error(`vgai: auto-open via ${cmd} exited ${code}: ${stderr}`);
|
|
64
|
+
fallback?.();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
child.unref();
|
|
69
|
+
|
|
70
|
+
const pipeTimeout = setTimeout(() => {
|
|
71
|
+
child.stderr?.destroy();
|
|
72
|
+
}, OPENER_EXIT_WATCH_TIMEOUT_MS);
|
|
73
|
+
pipeTimeout.unref();
|
|
74
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE on-disk shape of `<project>/logs/play-*.jsonl` — one definition, shared
|
|
3
|
+
* by the writer (`editor-server.ts`'s `/__editor/log-session` +
|
|
4
|
+
* `/__editor/log-entries` handlers) and every reader (`play.log.*` here,
|
|
5
|
+
* `vgai status`'s play-error banner, the project Analytics utility).
|
|
6
|
+
*
|
|
7
|
+
* A play log is JSONL with TWO record kinds:
|
|
8
|
+
*
|
|
9
|
+
* 1. THE HEADER — always the FIRST line, written when the file is opened:
|
|
10
|
+
* `{"kind":"session","v":1,"session":…,"project":…,"run":…,"startedAt":…}`.
|
|
11
|
+
* This is where the run's IDENTITY lives, recorded ONCE. The alternative
|
|
12
|
+
* (stamping session/project onto every entry) pays the same constant
|
|
13
|
+
* thousands of times per run for facts that cannot change while the file
|
|
14
|
+
* is open — the file is opened by one session, for one project, at one
|
|
15
|
+
* instant.
|
|
16
|
+
* 2. ENTRIES — every later line: `{t, level, source?, sub?, msg, meta?,
|
|
17
|
+
* tick?, simT?, world?, simSpeed?}`. Only genuinely per-entry facts go
|
|
18
|
+
* here: `tick`/`simT` (the frame the line was written on), `simSpeed`
|
|
19
|
+
* (the live time scale, which an instrument can change mid-run) and
|
|
20
|
+
* `world` (the world the run is presenting, unknown until the roots
|
|
21
|
+
* mount — so the entries written during boot honestly carry none).
|
|
22
|
+
*
|
|
23
|
+
* A reader must SKIP the header when counting or listing entries
|
|
24
|
+
* (`asPlayLogHeader` is the one test), and must tolerate its ABSENCE: logs
|
|
25
|
+
* written before the header existed are still on disk in real projects, and
|
|
26
|
+
* "no header" means "this run's identity was never recorded", never an error.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** `kind` value marking a play log's header line. */
|
|
30
|
+
export const PLAY_LOG_HEADER_KIND = 'session';
|
|
31
|
+
|
|
32
|
+
/** Bumped only when the on-disk record shapes change incompatibly. */
|
|
33
|
+
export const PLAY_LOG_FORMAT_VERSION = 1;
|
|
34
|
+
|
|
35
|
+
/** The run identity a play log carries on its first line. */
|
|
36
|
+
export interface PlayLogHeader {
|
|
37
|
+
readonly kind: typeof PLAY_LOG_HEADER_KIND;
|
|
38
|
+
readonly v: number;
|
|
39
|
+
/** The editor session that opened the file (`processSessionId()`) — the same
|
|
40
|
+
* id `vgai sessions` lists, so a log file names the session that wrote it. */
|
|
41
|
+
readonly session: string;
|
|
42
|
+
/** Absolute project root the session was serving. */
|
|
43
|
+
readonly project: string;
|
|
44
|
+
/** The run's slug (`vgai play --name <text>`), `null` for an unnamed run —
|
|
45
|
+
* the same slug that goes in the filename and the session journal. */
|
|
46
|
+
readonly run: string | null;
|
|
47
|
+
/** Wall-clock ms at which the file was opened. */
|
|
48
|
+
readonly startedAt: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The header line (newline included) for a run's identity. */
|
|
52
|
+
export function playLogHeaderLine(identity: Omit<PlayLogHeader, 'kind' | 'v'>): string {
|
|
53
|
+
const header: PlayLogHeader = {
|
|
54
|
+
kind: PLAY_LOG_HEADER_KIND,
|
|
55
|
+
v: PLAY_LOG_FORMAT_VERSION,
|
|
56
|
+
...identity,
|
|
57
|
+
};
|
|
58
|
+
return `${JSON.stringify(header)}\n`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** The parsed header, or `null` when this record is an ordinary entry (or a
|
|
62
|
+
* header from an unreadable/older shape). Every reader's one header test. */
|
|
63
|
+
export function asPlayLogHeader(record: unknown): PlayLogHeader | null {
|
|
64
|
+
if (typeof record !== 'object' || record === null || Array.isArray(record)) return null;
|
|
65
|
+
const rec = record as Record<string, unknown>;
|
|
66
|
+
if (rec['kind'] !== PLAY_LOG_HEADER_KIND) return null;
|
|
67
|
+
if (typeof rec['session'] !== 'string' || typeof rec['project'] !== 'string') return null;
|
|
68
|
+
return {
|
|
69
|
+
kind: PLAY_LOG_HEADER_KIND,
|
|
70
|
+
v: typeof rec['v'] === 'number' ? rec['v'] : 0,
|
|
71
|
+
session: rec['session'],
|
|
72
|
+
project: rec['project'],
|
|
73
|
+
run: typeof rec['run'] === 'string' ? rec['run'] : null,
|
|
74
|
+
startedAt: typeof rec['startedAt'] === 'number' ? rec['startedAt'] : 0,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Gameplay Session RECORD, as pure functions over the play log's text.
|
|
3
|
+
* The server derives the catalog from `logs/*.jsonl` on disk
|
|
4
|
+
* (`server/gameplay-sessions.ts`, which keeps its stat-keyed cache and fs
|
|
5
|
+
* wiring and calls in here); the functions themselves touch no filesystem, so
|
|
6
|
+
* the rules live in one place. They are subtle enough to fork badly — the
|
|
7
|
+
* torn live-append tail, the
|
|
8
|
+
* `ended` marker, the three-message recording lifecycle — which is why they
|
|
9
|
+
* live HERE and nowhere twice.
|
|
10
|
+
*
|
|
11
|
+
* Also home to the retention budgets, for the same reason: two copies of a
|
|
12
|
+
* byte budget is how two readers start keeping different histories.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { asPlayLogHeader } from './log-format';
|
|
16
|
+
|
|
17
|
+
/** Structured logs are the durable Analytics source. At the current event
|
|
18
|
+
* density this keeps hundreds of substantial sessions, without allowing one
|
|
19
|
+
* project to grow forever. */
|
|
20
|
+
export const GAMEPLAY_SESSION_LOG_BUDGET_BYTES = 256 * 1024 * 1024;
|
|
21
|
+
|
|
22
|
+
/** Automatically named session clips are working evidence, not keepsakes.
|
|
23
|
+
* Two GiB provides a useful history while making long recordings pay their
|
|
24
|
+
* actual disk cost. Explicitly named recordings are outside this budget. */
|
|
25
|
+
export const GAMEPLAY_SESSION_CLIP_BUDGET_BYTES = 2 * 1024 * 1024 * 1024;
|
|
26
|
+
|
|
27
|
+
export interface GameplaySessionRecording {
|
|
28
|
+
readonly format: 'composite-webm' | 'canvas-dom';
|
|
29
|
+
readonly replay: string | null;
|
|
30
|
+
readonly file: string;
|
|
31
|
+
readonly url: string;
|
|
32
|
+
readonly startedAt: number | null;
|
|
33
|
+
readonly finalized: boolean;
|
|
34
|
+
readonly bytes: number | null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface GameplaySessionRecord {
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly run: string | null;
|
|
40
|
+
readonly status: 'live' | 'completed';
|
|
41
|
+
readonly startedAt: number;
|
|
42
|
+
readonly endedAt: number | null;
|
|
43
|
+
readonly durationMs: number;
|
|
44
|
+
readonly logFile: string;
|
|
45
|
+
readonly entries: readonly Record<string, unknown>[];
|
|
46
|
+
readonly recording: GameplaySessionRecording | null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ParsedGameplaySession {
|
|
50
|
+
readonly id: string;
|
|
51
|
+
readonly run: string | null;
|
|
52
|
+
readonly startedAt: number;
|
|
53
|
+
readonly endedAt: number | null;
|
|
54
|
+
readonly logFile: string;
|
|
55
|
+
readonly entries: readonly Record<string, unknown>[];
|
|
56
|
+
readonly recording: GameplaySessionRecording | null;
|
|
57
|
+
readonly fallbackEndedAt: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function numberField(value: unknown): number | null {
|
|
61
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** A bare filename — no path separators. The same refusal the server's
|
|
65
|
+
* `basename(file) !== file` check made, path-module-free. */
|
|
66
|
+
function isBareFilename(file: string): boolean {
|
|
67
|
+
return file.length > 0 && !file.includes('/') && !file.includes('\\');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: this is a small single-pass reducer over three recording lifecycle messages.
|
|
71
|
+
function recordingEvent(
|
|
72
|
+
entries: readonly Record<string, unknown>[],
|
|
73
|
+
): Omit<GameplaySessionRecording, 'url'> | null {
|
|
74
|
+
type RecordingState = Omit<GameplaySessionRecording, 'url'>;
|
|
75
|
+
let current: RecordingState | null = null;
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (entry['source'] !== 'gameplay-recording') continue;
|
|
78
|
+
const meta = entry['meta'];
|
|
79
|
+
if (typeof meta !== 'object' || meta === null || Array.isArray(meta)) continue;
|
|
80
|
+
const fields = meta as Record<string, unknown>;
|
|
81
|
+
const file = fields['file'];
|
|
82
|
+
if (typeof file !== 'string' || !isBareFilename(file)) continue;
|
|
83
|
+
if (entry['msg'] === 'started') {
|
|
84
|
+
current = {
|
|
85
|
+
file,
|
|
86
|
+
format: fields['format'] === 'canvas-dom' ? 'canvas-dom' : 'composite-webm',
|
|
87
|
+
replay: null,
|
|
88
|
+
startedAt: numberField(fields['startedAt']),
|
|
89
|
+
finalized: false,
|
|
90
|
+
bytes: null,
|
|
91
|
+
};
|
|
92
|
+
} else if (entry['msg'] === 'finalized') {
|
|
93
|
+
const existing = current as RecordingState | null;
|
|
94
|
+
if (existing?.file === file) {
|
|
95
|
+
current = {
|
|
96
|
+
...existing,
|
|
97
|
+
finalized: true,
|
|
98
|
+
bytes: numberField(fields['bytes']),
|
|
99
|
+
replay:
|
|
100
|
+
typeof fields['replay'] === 'string' && isBareFilename(fields['replay'])
|
|
101
|
+
? fields['replay']
|
|
102
|
+
: null,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
} else if (
|
|
106
|
+
(current as RecordingState | null)?.file === file &&
|
|
107
|
+
(entry['msg'] === 'aborted' || entry['msg'] === 'evicted')
|
|
108
|
+
) {
|
|
109
|
+
current = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return current;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface ParsePlayLogOptions {
|
|
116
|
+
/** The log's bare filename, e.g. `play-2026-…-0001.jsonl`. */
|
|
117
|
+
readonly file: string;
|
|
118
|
+
/** What "ended" means when the log carries no `ended` marker (a crashed
|
|
119
|
+
* run): the file's own last-modified time on tiers that know it, or the
|
|
120
|
+
* read time otherwise. */
|
|
121
|
+
readonly fallbackEndedAt: number;
|
|
122
|
+
/** How this tier addresses the session's recording, when one survives the
|
|
123
|
+
* lifecycle reduce — the server serves a route, the browser has none. */
|
|
124
|
+
readonly recordingUrl: (sessionId: string, recordingFile: string) => string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Parse one play log's raw text into the session record's parsed half, or
|
|
129
|
+
* `null` when the first line is not a play-log identity header (any other
|
|
130
|
+
* JSONL in `logs/` is not a session).
|
|
131
|
+
*/
|
|
132
|
+
export function parsePlayLogText(
|
|
133
|
+
raw: string,
|
|
134
|
+
options: ParsePlayLogOptions,
|
|
135
|
+
): ParsedGameplaySession | null {
|
|
136
|
+
const records: unknown[] = [];
|
|
137
|
+
for (const line of raw.split('\n')) {
|
|
138
|
+
if (line.trim() === '') continue;
|
|
139
|
+
try {
|
|
140
|
+
records.push(JSON.parse(line) as unknown);
|
|
141
|
+
} catch {
|
|
142
|
+
// A live append may expose a torn tail. Everything before it remains a
|
|
143
|
+
// valid session record and the next poll will pick up the completed row.
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const header = asPlayLogHeader(records[0]);
|
|
147
|
+
if (!header) return null;
|
|
148
|
+
const entries = records
|
|
149
|
+
.slice(1)
|
|
150
|
+
.filter(
|
|
151
|
+
(value): value is Record<string, unknown> =>
|
|
152
|
+
typeof value === 'object' && value !== null && !Array.isArray(value),
|
|
153
|
+
);
|
|
154
|
+
const end = [...entries]
|
|
155
|
+
.reverse()
|
|
156
|
+
.find((entry) => entry['source'] === 'gameplay-session' && entry['msg'] === 'ended');
|
|
157
|
+
const endMeta =
|
|
158
|
+
typeof end?.['meta'] === 'object' && end['meta'] !== null && !Array.isArray(end['meta'])
|
|
159
|
+
? (end['meta'] as Record<string, unknown>)
|
|
160
|
+
: null;
|
|
161
|
+
const recording = recordingEvent(entries);
|
|
162
|
+
const id = options.file.replace(/\.[^.]*$/, '');
|
|
163
|
+
return {
|
|
164
|
+
id,
|
|
165
|
+
run: header.run,
|
|
166
|
+
startedAt: header.startedAt,
|
|
167
|
+
endedAt: numberField(endMeta?.['endedAt']),
|
|
168
|
+
fallbackEndedAt: options.fallbackEndedAt,
|
|
169
|
+
logFile: `logs/${options.file}`,
|
|
170
|
+
entries,
|
|
171
|
+
recording: recording ? { ...recording, url: options.recordingUrl(id, recording.file) } : null,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Project a parsed session against the tier's live state: the active log (if
|
|
177
|
+
* this is it, the session is `live` and its edge is `now`) or the recorded /
|
|
178
|
+
* fallback end.
|
|
179
|
+
*/
|
|
180
|
+
export function materializeGameplaySession(
|
|
181
|
+
parsed: ParsedGameplaySession,
|
|
182
|
+
options: { readonly activeLogBaseName: string | null; readonly now: number },
|
|
183
|
+
): GameplaySessionRecord {
|
|
184
|
+
const active =
|
|
185
|
+
options.activeLogBaseName !== null && parsed.logFile === `logs/${options.activeLogBaseName}`;
|
|
186
|
+
const endedAt = active ? null : (parsed.endedAt ?? parsed.fallbackEndedAt);
|
|
187
|
+
const liveEdge = active ? options.now : (endedAt ?? parsed.fallbackEndedAt);
|
|
188
|
+
return {
|
|
189
|
+
id: parsed.id,
|
|
190
|
+
run: parsed.run,
|
|
191
|
+
status: active ? 'live' : 'completed',
|
|
192
|
+
startedAt: parsed.startedAt,
|
|
193
|
+
endedAt,
|
|
194
|
+
durationMs: Math.max(0, liveEdge - parsed.startedAt),
|
|
195
|
+
logFile: parsed.logFile,
|
|
196
|
+
entries: parsed.entries,
|
|
197
|
+
recording: parsed.recording,
|
|
198
|
+
};
|
|
199
|
+
}
|