@vgai/editor 0.2.0 → 0.4.0-canary.20260715.0
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/README.md +24 -0
- package/dist/assets/axe-C7YBtOuM.js +30 -0
- package/dist/assets/browserAll-DDtGGE48.js +1 -0
- package/dist/assets/create-runtime-DbTlBlKG.js +1 -0
- package/dist/assets/{game-BI111o5f.js → game-BE0r7DMI.js} +3 -3
- package/dist/assets/game-BdTHR2_X.js +1 -0
- package/dist/assets/{game-pt_1lQLv.js → game-C3iQGSqo.js} +1 -1
- package/dist/assets/game-CcHfYxjP.js +1 -0
- package/dist/assets/game-Cqzj_lpD.js +1 -0
- package/dist/assets/game-DSZdeCHu.js +1 -0
- package/dist/assets/game-Dch9sAPc.js +1 -0
- package/dist/assets/{game-xsOho_wg.js → game-SAFn90pA.js} +3 -3
- package/dist/assets/game-loop-DMIgSMV-.js +1 -0
- package/dist/assets/{game-source-CvidN7AB.js → game-source-Dk83w26t.js} +1 -1
- package/dist/assets/{index-Bp5cecD6.js → index-4idIsHHJ.js} +2 -2
- package/dist/assets/{index-DL7RcQ0n.js → index-C-LhOTBN.js} +1 -1
- package/dist/assets/{index-Cs8xwv3e.js → index-CDkxceqE.js} +1 -1
- package/dist/assets/index-CQEfi217.js +15412 -0
- package/dist/assets/index-Dvi-V0NE.css +1 -0
- package/dist/assets/ingest-siblings-s0P5I1Ub.js +1 -0
- package/dist/assets/mount-manifest-DXMOlF79.js +1 -0
- package/dist/assets/react-18-C9eHn8x1.js +1 -0
- package/dist/assets/webworkerAll-Fn0e-ouF.js +1 -0
- package/dist/assets/world-documents-GM0a9Kv7.js +1 -0
- package/dist/index.html +15 -13
- package/dist/ingest/racing-game/vgai.game.json +5 -4
- package/dist/ingest/simcity/vgai.game.json +5 -4
- package/dist/ingest/tanks/vgai.game.json +5 -4
- package/dist/project-scripts.bundle.js +3917 -0
- package/dist/scenes/untitled.vscn.json +2 -0
- package/dist-server/packaged.mjs +7697 -3435
- package/package.json +31 -4
- package/scripts/probe-reporter.ts +349 -0
- package/scripts/run-probe.ts +2260 -0
- package/server/asset-catalog-audit.ts +268 -0
- package/server/asset-catalog-v2.ts +146 -0
- package/server/asset-library-routes.ts +276 -58
- package/server/canonical-path.ts +1 -1
- package/server/dev.ts +148 -44
- package/server/editor-server.ts +888 -61
- package/server/editor-sse.ts +115 -4
- package/server/harness-chat-service.ts +796 -0
- package/server/local-asset-catalog.ts +157 -22
- package/server/packaged.ts +51 -21
- package/server/process-shutdown.ts +136 -0
- package/server/prod.ts +9 -6
- package/server/project-hmr-files.ts +41 -0
- package/server/project-operations.ts +343 -0
- package/server/project-optimize-deps-entries.ts +4 -4
- package/server/project-output-writer.ts +156 -0
- package/server/project-validation.ts +140 -0
- package/server/project-view.ts +8 -50
- package/server/server-utils.ts +75 -10
- package/server/session-registry.ts +12 -0
- package/src/EditorContext.tsx +107 -3
- package/src/action-registry.ts +115 -17
- package/src/adapter-resolver.ts +213 -478
- package/src/asset-events.ts +64 -1
- package/src/asset-preview.ts +906 -0
- package/src/asset-selection.ts +121 -0
- package/src/asset-workflow/asset-capabilities.ts +259 -0
- package/src/asset-workflow/asset-editor-errors.ts +46 -0
- package/src/asset-workflow/asset-import-pipeline.ts +176 -0
- package/src/asset-workflow/asset-library-query.ts +107 -0
- package/src/asset-workflow/asset-types.ts +192 -0
- package/src/asset-workflow/asset-workflow-quality.ts +65 -0
- package/src/asset-workflow/import-contract.ts +113 -0
- package/src/asset-workflow/model-conversion.ts +126 -0
- package/src/asset-workflow/model-inspection.ts +185 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +153 -0
- package/src/asset-workflow/project-asset-operations.ts +119 -0
- package/src/asset-workflow/thumbnail-system.ts +172 -0
- package/src/authoring/active-systems.ts +15 -0
- package/src/authoring/boundary-authoring-adapter.ts +16 -5
- package/src/authoring/composite-authoring-adapter.ts +305 -124
- package/src/authoring/design-time-layers.ts +300 -117
- package/src/authoring/edit-mode-authoring.ts +278 -293
- package/src/authoring/embed-only-adapter.ts +4 -2
- package/src/authoring/first-party-hierarchy-menu.ts +7 -2
- package/src/authoring/first-party-inspector/AddSectionMenu.tsx +5 -12
- package/src/authoring/first-party-inspector/EnvironmentSection.tsx +53 -126
- package/src/authoring/first-party-inspector/HeaderSection.tsx +54 -65
- package/src/authoring/first-party-inspector/is-first-party-selection.ts +30 -11
- package/src/authoring/first-party-inspector/register.tsx +13 -2
- package/src/authoring/ingest-authoring-adapter.ts +142 -45
- package/src/authoring/mount-failure-report.ts +5 -5
- package/src/authoring/provenance.ts +41 -0
- package/src/authoring/react-dom-authoring-adapter.ts +92 -92
- package/src/authoring/react-inspector-section.tsx +489 -51
- package/src/authoring/react-world-authoring-adapter.ts +541 -306
- package/src/authoring/story-overlay.ts +1 -1
- package/src/authoring/story-types.ts +11 -0
- package/src/authoring/vgai-scene-authoring-adapter.ts +54 -25
- package/src/authoring/viewport-tool-context.ts +78 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +186 -0
- package/src/authoring/world-pan-state.ts +33 -17
- package/src/authoring/world-session-state.ts +1 -1
- package/src/authoring/world2d-authoring-adapter.ts +109 -52
- package/src/availability-tick.ts +56 -0
- package/src/browser-play-entry.ts +5 -5
- package/src/browser-project-scripts.ts +1 -0
- package/src/build-identity.ts +15 -0
- package/src/command-listener.ts +893 -19
- package/src/components/AlignToolbar.tsx +74 -63
- package/src/components/AppRoot.tsx +193 -26
- package/src/components/ApplicationMenus.tsx +272 -0
- package/src/components/AssetBrowser.tsx +1450 -293
- package/src/components/AssetEditorShell.tsx +141 -0
- package/src/components/AssetImportDetails.tsx +218 -0
- package/src/components/AssetLibraryPanel.tsx +14 -0
- package/src/components/CameraInfo.tsx +11 -20
- package/src/components/CenterDocuments.tsx +585 -0
- package/src/components/CommandPalette.tsx +75 -30
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +57 -112
- package/src/components/DebugConsolePanel.tsx +461 -0
- package/src/components/DebuggerPanel.tsx +165 -0
- package/src/components/DefaultEditorLayout.tsx +167 -231
- package/src/components/GameHierarchy.tsx +873 -290
- package/src/components/GamePerformanceOverlay.tsx +46 -0
- package/src/components/HarnessChatPanel.tsx +2352 -0
- package/src/components/HistoryPanel.tsx +226 -0
- package/src/components/Inspector.tsx +153 -99
- package/src/components/InspectorToolSection.tsx +6 -4
- package/src/components/MountFailureBanner.tsx +31 -48
- package/src/components/NetworkSection.tsx +25 -14
- package/src/components/OnlineAssetBrowser.tsx +794 -343
- package/src/components/OverlayReportBanner.tsx +38 -64
- package/src/components/PerformancePanel.tsx +206 -0
- package/src/components/PlayBar.tsx +93 -263
- package/src/components/PrefabSaveDialog.tsx +55 -127
- package/src/components/ProjectHeader.css +60 -0
- package/src/components/ProjectHeader.tsx +170 -105
- package/src/components/ProjectScreen.tsx +246 -184
- package/src/components/ReactCanvasControls.tsx +185 -0
- package/src/components/ResolutionPicker.tsx +85 -0
- package/src/components/RootActivateDialog.tsx +39 -68
- package/src/components/SaveDialog.tsx +55 -127
- package/src/components/SaveStatus.tsx +11 -29
- package/src/components/StartupLoadingScreen.tsx +96 -0
- package/src/components/StateWatchPanel.tsx +302 -0
- package/src/components/StatsOverlay.tsx +12 -5
- package/src/components/StatusBar.tsx +64 -0
- package/src/components/ThemeManagerDialog.css +89 -0
- package/src/components/ThemeManagerDialog.tsx +371 -0
- package/src/components/ToolHost.tsx +26 -15
- package/src/components/Toolbar.tsx +117 -214
- package/src/components/VgaiVoxelLogo.tsx +89 -0
- package/src/components/ViewportOverlay.tsx +97 -172
- package/src/components/ViewportPanel.tsx +130 -31
- package/src/components/WorkspaceDock.tsx +891 -0
- package/src/components/WorldSelectionOverlay.tsx +51 -63
- package/src/components/WorldTextEditor.tsx +9 -5
- package/src/components/asset-documents.tsx +390 -0
- package/src/components/asset-editor-persistence.ts +44 -0
- package/src/components/asset-selection-section.tsx +338 -0
- package/src/components/asset-viewers/AudioViewer.tsx +73 -21
- package/src/components/asset-viewers/GenericJsonViewer.tsx +26 -11
- package/src/components/asset-viewers/ImageViewer.tsx +43 -11
- package/src/components/asset-viewers/InputMapViewer.tsx +512 -134
- package/src/components/asset-viewers/MaterialAssetEditor.tsx +540 -0
- package/src/components/asset-viewers/ModelViewer.tsx +805 -121
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +177 -60
- package/src/components/asset-viewers/SourceAssetViewer.tsx +121 -0
- package/src/components/asset-workflow.css +506 -0
- package/src/components/build-documents.tsx +696 -0
- package/src/components/core-utilities.tsx +75 -0
- package/src/components/data-documents.tsx +364 -0
- package/src/components/{DataPanel.tsx → data-editor.tsx} +138 -288
- package/src/components/debugger-panel-state.ts +57 -0
- package/src/components/inspector-widgets/AlignmentGrid.tsx +8 -14
- package/src/components/inspector-widgets/BorderEditor.tsx +41 -33
- package/src/components/inspector-widgets/ColorPicker.tsx +39 -39
- package/src/components/inspector-widgets/FontPicker.tsx +13 -21
- package/src/components/inspector-widgets/GradientEditor.tsx +11 -19
- package/src/components/inspector-widgets/ScrubbableInput.tsx +6 -3
- package/src/components/inspector-widgets/ShadowEditor.tsx +20 -33
- package/src/components/inspector-widgets/shared.tsx +90 -49
- package/src/components/inspectors/AnimationSection.tsx +39 -40
- package/src/components/inspectors/AudioSection.tsx +28 -39
- package/src/components/inspectors/BoneAttachmentSection.tsx +19 -24
- package/src/components/inspectors/CameraSection.tsx +14 -23
- package/src/components/inspectors/ComponentsSection.tsx +39 -43
- package/src/components/inspectors/JointsSection.tsx +34 -43
- package/src/components/inspectors/LightSection.tsx +90 -35
- package/src/components/inspectors/MaterialSection.tsx +137 -174
- package/src/components/inspectors/MeshSection.tsx +9 -17
- package/src/components/inspectors/NavigationSection.tsx +8 -15
- package/src/components/inspectors/ParticleSection.tsx +91 -76
- package/src/components/inspectors/PhysicsSection.tsx +42 -46
- package/src/components/inspectors/PostProcessingSection.tsx +28 -36
- package/src/components/inspectors/RenderingSection.tsx +12 -20
- package/src/components/inspectors/ShadowSection.tsx +7 -8
- package/src/components/inspectors/SplineSection.tsx +31 -42
- package/src/components/inspectors/TransformSection.tsx +14 -22
- package/src/components/patterns/Dialog.tsx +95 -0
- package/src/components/patterns/Fields.tsx +44 -0
- package/src/components/patterns/List.tsx +25 -0
- package/src/components/patterns/StateSurface.tsx +40 -0
- package/src/components/patterns/Surfaces.tsx +115 -0
- package/src/components/patterns/Tabs.tsx +80 -0
- package/src/components/patterns/Toolbar.tsx +51 -0
- package/src/components/patterns/Tree.tsx +72 -0
- package/src/components/primitives/Button.tsx +46 -0
- package/src/components/primitives/ColorInput.tsx +11 -47
- package/src/components/primitives/EditorIcon.tsx +99 -0
- package/src/components/primitives/FormControls.tsx +71 -0
- package/src/components/primitives/JsonInput.tsx +15 -2
- package/src/components/primitives/Layout.tsx +100 -0
- package/src/components/primitives/Menu.tsx +105 -0
- package/src/components/primitives/NumberInput.tsx +8 -35
- package/src/components/primitives/Panel.tsx +49 -44
- package/src/components/primitives/SectionHeader.tsx +10 -28
- package/src/components/primitives/Text.tsx +46 -0
- package/src/components/primitives/Tooltip.tsx +20 -12
- package/src/components/primitives/Vec3Input.tsx +3 -0
- package/src/components/primitives/banner-tones.ts +33 -0
- package/src/components/primitives/editor-icons.ts +102 -0
- package/src/components/primitives/panel-header-styles.ts +30 -0
- package/src/components/project-operation-documents.tsx +226 -0
- package/src/components/status-contributions.tsx +175 -0
- package/src/components/story-documents-register.ts +15 -0
- package/src/components/story-documents.tsx +1185 -0
- package/src/components/tool-documents.tsx +110 -0
- package/src/components/workspace-dock.css +293 -0
- package/src/components/workspace-history.ts +33 -0
- package/src/components/world-documents.tsx +145 -0
- package/src/components/xstate-documents.tsx +209 -0
- package/src/composite-screenshot.ts +248 -0
- package/src/design-system/index.ts +70 -0
- package/src/design-system-stories/Foundation.stories.tsx +183 -0
- package/src/design-system-stories/Patterns.stories.tsx +251 -0
- package/src/design-system-stories/Workspace.stories.tsx +538 -0
- package/src/doctor/report.ts +57 -13
- package/src/editor-api.ts +295 -31
- package/src/editor-compatibility.ts +200 -0
- package/src/editor-console.ts +35 -17
- package/src/editor-hotkeys.ts +85 -33
- package/src/editor-store.ts +538 -233
- package/src/editor-viewport.ts +160 -34
- package/src/entity-factory.ts +14 -3
- package/src/gizmo-registry.ts +21 -5
- package/src/harness-chat-editor-context.ts +37 -0
- package/src/harness-chat-indicator.ts +68 -0
- package/src/harness-chat-layout.ts +53 -0
- package/src/harness-chat-lifecycle.ts +170 -0
- package/src/harness-chat-reconnect.ts +85 -0
- package/src/harness-chat-types.ts +409 -0
- package/src/hierarchy-drop.ts +50 -0
- package/src/hierarchy-expansion-state.ts +100 -0
- package/src/hierarchy-menu-registry.ts +1 -1
- package/src/hierarchy-projection.ts +76 -0
- package/src/history/editor-session.ts +21 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-service.ts +904 -0
- package/src/history/json-history-resource.ts +165 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +266 -0
- package/src/history/project-root-history-backends.ts +53 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +108 -0
- package/src/history/source-history-backend.ts +374 -0
- package/src/history/types.ts +100 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hosted-example.ts +12 -2
- package/src/hotkeys.ts +89 -18
- package/src/ingest/discovery-react.ts +9 -10
- package/src/ingest/discovery.ts +4 -4
- package/src/ingest/discovery2d.ts +5 -5
- package/src/ingest/games/bloom-composer/vgai.game.json +3 -3
- package/src/ingest/games/embed-bundle/vgai.game.json +3 -3
- package/src/ingest/games/games-fps/vgai.game.json +3 -3
- package/src/ingest/games/iframe-reachable/vgai.game.json +3 -3
- package/src/ingest/games/interactive-cubes/vgai.game.json +3 -3
- package/src/ingest/games/mismatched-three/vgai.game.json +3 -3
- package/src/ingest/games/own-three-bundled/vgai.game.json +3 -3
- package/src/ingest/games/pointerlock-maze/vgai.game.json +7 -4
- package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +3 -3
- package/src/ingest/games-2d/bunnymark/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy/vgai.game.json +3 -3
- package/src/ingest/games-2d/flappy-pixi/vgai.game.json +3 -3
- package/src/ingest/games-2d/puzzling-potions/vgai.game.json +3 -3
- package/src/ingest/games-2d/tilemap-camera/vgai.game.json +3 -3
- package/src/ingest/games-react/react-rpg/vgai.game.json +3 -3
- package/src/ingest/types.ts +1 -1
- package/src/ingest-mode.ts +47 -52
- package/src/ingest-siblings.ts +23 -33
- package/src/initial-scene.ts +1 -2
- package/src/main.tsx +16 -8
- package/src/manifest-project.ts +10 -12
- package/src/model-thumbnail.ts +261 -26
- package/src/module-mode.ts +44 -50
- package/src/play-log-events.ts +26 -0
- package/src/play-mode.ts +495 -401
- package/src/play-scene-adoption.ts +23 -0
- package/src/playground/main.ts +68 -24
- package/src/playwright-shim.ts +473 -0
- package/src/project-manager.ts +90 -10
- package/src/project-operations.ts +112 -0
- package/src/project-story-discovery.ts +25 -0
- package/src/project-tool-discovery.ts +43 -0
- package/src/scene-serializer.ts +0 -6
- package/src/scene-sync.ts +7 -2
- package/src/script-loader.ts +3 -3
- package/src/skeleton-helper.ts +57 -0
- package/src/storage/seed.ts +68 -8
- package/src/stories/StoryPreviewMount.tsx +265 -0
- package/src/stories/action-stories.fixture.tsx +44 -0
- package/src/stories/button-stories.fixture.tsx +50 -0
- package/src/stories/compose-project-stories.ts +182 -0
- package/src/stories/loader-stories.fixture.tsx +53 -0
- package/src/stories/story-discovery.ts +130 -0
- package/src/stories/story-registry.ts +146 -0
- package/src/theme-css.ts +1049 -0
- package/src/theme-library.ts +238 -0
- package/src/theme-preference.ts +130 -0
- package/src/theme.ts +527 -0
- package/src/tool-loader.ts +80 -24
- package/src/ui-source/inspect.ts +27 -4
- package/src/ui-source/source-write-backend.ts +83 -22
- package/src/widgets/index.ts +9 -18
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-dock-controller.ts +64 -0
- package/src/workspace-document-ids.ts +5 -0
- package/src/workspace-document-registry.ts +367 -0
- package/src/workspace-state-persistence.ts +455 -0
- package/src/workspace-status-registry.ts +110 -0
- package/src/workspace-utility-commands.ts +49 -0
- package/src/workspace-utility-registry.ts +161 -0
- package/src/world-document-routing.ts +16 -0
- package/src/xstate-inspect/XStateMachineInspector.tsx +544 -0
- package/src/xstate-inspect/character-animation-machine.fixture.ts +74 -0
- package/src/xstate-inspect/use-live-actor-state.ts +39 -0
- package/src/xstate-inspect/xstate-graph.ts +265 -0
- package/src/xstate-inspect/xstate-layout.ts +76 -0
- package/src/z-index.ts +26 -0
- package/template/.claude/skills/editor/SKILL.md +129 -90
- package/template/AGENTS.md +1110 -0
- package/template/CLAUDE.md +1 -512
- package/template/IDIOMS.md +50 -0
- package/template/check-idioms.ts +706 -0
- package/template/manifest-entry-modules-plugin.ts +53 -0
- package/template/package.json +13 -4
- package/template/public/scenes/default.scn2d.json +6 -0
- package/template/public/scenes/default.vscn.json +7 -1
- package/template/public/scenes/untitled.vscn.json +10 -0
- package/template/scripts/playtest.ts +40 -0
- package/template/server/loopback.ts +75 -0
- package/template/server/rooms/arena-room.ts +69 -1
- package/template/server/rooms/game-room.ts +68 -1
- package/template/src/data/README.md +9 -4
- package/template/src/data/data-ref.ts +35 -0
- package/template/src/data/tuning.schema.ts +1 -1
- package/template/src/main.ts +41 -62
- package/template/src/manifest-entry-modules.d.ts +3 -0
- package/template/src/operations/README.md +88 -0
- package/template/src/runtime/pixi-adapter.ts +24 -0
- package/template/src/scripts/components/data-spinner.ts +43 -2
- package/template/src/scripts/components/spin-lap-math.ts +27 -0
- package/template/src/tools/README.md +5 -3
- package/template/src/tools/example.tool.tsx +13 -7
- package/template/src/ui/Button.stories.tsx +66 -0
- package/template/src/ui/RebindPanel.tsx +2 -6
- package/template/src/ui/game.tsx +17 -0
- package/template/tests/acceptance/example.spec.ts +64 -0
- package/template/tests/logic/example.test.ts +31 -0
- package/template/tests/logic/room.test.ts +100 -0
- package/template/tests/tsconfig.json +30 -0
- package/template/validate-manifest.ts +5 -5
- package/template/validate-scenes.ts +50 -18
- package/template/vgai.game.json +20 -13
- package/template/vite.config.ts +77 -16
- package/vite-plugin-ui-oid.ts +261 -17
- package/dist/assets/CCDIKSolver-Dz-ysxZF.js +0 -1
- package/dist/assets/SelectionBox-BXsv_6aH.js +0 -1
- package/dist/assets/browser-project-scripts-DOru4L1x.js +0 -2
- package/dist/assets/browserAll-CEkWYlFk.js +0 -1
- package/dist/assets/create-runtime-DYIWr3va.js +0 -1
- package/dist/assets/data-asset-Bb9sIM7i.js +0 -5
- package/dist/assets/game-8SDZPPgH.js +0 -1
- package/dist/assets/game-CevorxyV.js +0 -1
- package/dist/assets/game-Di7XlywD.js +0 -1
- package/dist/assets/game-DjnCaw8R.js +0 -1
- package/dist/assets/game-Q9A0aXSV.js +0 -1
- package/dist/assets/index-CPVV6pjw.js +0 -1
- package/dist/assets/index-CpOnYyeD.js +0 -213
- package/dist/assets/index-Dr8H_6Rl.js +0 -1
- package/dist/assets/index-_bCaipUk.js +0 -13650
- package/dist/assets/ingest-siblings-Dz8eEqrV.js +0 -1
- package/dist/assets/mount-manifest-Bhk0ohsl.js +0 -1
- package/dist/assets/scene-query-BivAHhJu.js +0 -1
- package/dist/assets/webworkerAll-BLrH0F6F.js +0 -1
- package/dist/assets/xstate-animation-binding-1NGLmw6y.js +0 -1
- package/dist/assets/xstate.esm-BgUD33nl.js +0 -3
- package/src/authoring/scene-ui-layer.ts +0 -485
- package/src/authoring/ui-authoring-adapter.ts +0 -325
- package/src/authoring/ui-hierarchy-menu.ts +0 -40
- package/src/authoring/ui-inspector-sections.tsx +0 -156
- package/src/authoring/undo-timeline.ts +0 -145
- package/src/components/BottomPanel.tsx +0 -326
- package/src/components/BuildPanel.tsx +0 -455
- package/src/components/FolderTree.tsx +0 -179
- package/src/components/RightPanel.tsx +0 -166
- package/src/components/WorldContextMenu.tsx +0 -257
- package/src/components/asset-viewers/AssetViewer.tsx +0 -38
- package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +0 -129
- package/src/scene-ui-mode/active-scene-ui.ts +0 -58
- package/src/scene-ui-mode/scene-ui-palette-panel.tsx +0 -152
- package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +0 -29
- package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +0 -74
- package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +0 -49
- package/src/scene-ui-mode/ui-prefab-io.ts +0 -76
- package/src/ui-editor/inspector.tsx +0 -563
- package/src/ui-editor/node-ops.ts +0 -266
- package/src/ui-editor/overlay.tsx +0 -380
- package/src/ui-editor/palette.tsx +0 -114
- package/src/ui-editor/react-store.ts +0 -78
- package/src/ui-editor/timeline-panel.tsx +0 -443
- package/src/ui-editor/ui-edit-store.ts +0 -552
- package/src/ui-editor/ui-prefab.ts +0 -95
- package/template/project.json +0 -9
- package/template/src/scripts/main.ts +0 -94
- package/template/src/ui/DefaultHud.tsx +0 -40
- package/template/src/ui/game-state.tsx +0 -37
- package/template/src/ui/mount-default-hud.tsx +0 -19
- package/template/src/ui/mount-ui.ts +0 -15
- package/vite-plugin-react-world-provider.ts +0 -81
package/package.json
CHANGED
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
"name": "@vgai/editor",
|
|
3
3
|
"author": "Volter AI, Inc.",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.4.0-canary.20260715.0",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/volter-ai/vgai-engine.git",
|
|
10
|
+
"directory": "packages/editor"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
7
15
|
"files": [
|
|
8
16
|
"dist",
|
|
9
17
|
"dist-server",
|
|
10
18
|
"server",
|
|
19
|
+
"scripts/run-probe.ts",
|
|
20
|
+
"scripts/probe-reporter.ts",
|
|
11
21
|
"src",
|
|
12
22
|
"vite-plugin-*.ts",
|
|
13
23
|
"template"
|
|
@@ -17,20 +27,37 @@
|
|
|
17
27
|
},
|
|
18
28
|
"scripts": {
|
|
19
29
|
"build": "cd ../.. && npx vite build --outDir packages/editor/dist --emptyOutDir",
|
|
20
|
-
"build:server": "npx esbuild server/packaged.ts --bundle --platform=node --format=esm --outfile=dist-server/packaged.mjs --tsconfig=../../tsconfig.server.json --external:express --external:chokidar --external:vite --external:esbuild --external:typescript",
|
|
21
|
-
"prepack": "npm run build && npm run build:server"
|
|
30
|
+
"build:server": "npx esbuild server/packaged.ts --bundle --platform=node --format=esm --outfile=dist-server/packaged.mjs --tsconfig=../../tsconfig.server.json --external:express --external:chokidar --external:vite --external:esbuild --external:typescript --external:@volter-ai-dev/supercode-client --external:@volter-ai-dev/supercode-harness-sdk",
|
|
31
|
+
"prepack": "npm run build && npm run build:server",
|
|
32
|
+
"storybook": "storybook dev -p 6006 --config-dir .storybook",
|
|
33
|
+
"storybook:build": "storybook build --config-dir .storybook",
|
|
34
|
+
"storybook:test:visual": "playwright test -c playwright.storybook.config.ts"
|
|
22
35
|
},
|
|
23
36
|
"dependencies": {
|
|
37
|
+
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
|
38
|
+
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
|
39
|
+
"@fortawesome/react-fontawesome": "^3.2.0",
|
|
24
40
|
"@pixi/tilemap": "^5.0.0",
|
|
25
|
-
"@vgai/engine": "
|
|
41
|
+
"@vgai/engine": "0.4.0-canary.20260715.0",
|
|
42
|
+
"axe-core": "^4.12.1",
|
|
26
43
|
"chokidar": "^5.0.0",
|
|
44
|
+
"dockview-react": "^7.0.2",
|
|
27
45
|
"esbuild": "^0.25.12",
|
|
28
46
|
"express": "^5.2.1",
|
|
47
|
+
"react-markdown": "^10.1.0",
|
|
48
|
+
"remark-gfm": "^4.0.1",
|
|
29
49
|
"typescript": "^5.6.0",
|
|
30
50
|
"vite": "^6.0.0"
|
|
31
51
|
},
|
|
52
|
+
"optionalDependencies": {
|
|
53
|
+
"@volter-ai-dev/supercode": "^0.2.1",
|
|
54
|
+
"@volter-ai-dev/supercode-client": "^0.3.0",
|
|
55
|
+
"@volter-ai-dev/supercode-harness-sdk": "^0.2.0"
|
|
56
|
+
},
|
|
32
57
|
"devDependencies": {
|
|
58
|
+
"@storybook/addon-a11y": "^9.1.20",
|
|
33
59
|
"@storybook/react": "^9.1.20",
|
|
60
|
+
"@storybook/react-vite": "^9.1.20",
|
|
34
61
|
"storybook": "^9.1.20"
|
|
35
62
|
}
|
|
36
63
|
}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vgai probe`'s own Playwright reporter (ACCEPTANCE-DRIVER-BUILD-PLAN.md
|
|
3
|
+
* Task 3.4 steps 4/7, docs/ACCEPTANCE-DRIVER-SPEC.md §2.2) — writes the
|
|
4
|
+
* versioned `last-run.json` envelope every `vgai probe` run produces.
|
|
5
|
+
*
|
|
6
|
+
* This module is loaded by Playwright INSIDE the spawned `npx playwright
|
|
7
|
+
* test` process (referenced by absolute path from the generated config's
|
|
8
|
+
* `reporter` list — see `run-probe.ts`'s `buildProbeConfigSource`). It only
|
|
9
|
+
* ever sees Playwright's own Reporter API (`TestCase`/`TestResult`/
|
|
10
|
+
* `FullResult`) — never a live `Page`/`Browser` handle (those belong to the
|
|
11
|
+
* `game` fixture in `@vgai/probe`, a different module this reporter does not
|
|
12
|
+
* import and must not duplicate).
|
|
13
|
+
*
|
|
14
|
+
* Playwright's `TestError` type (`playwright/types/testReporter.d.ts`) has NO
|
|
15
|
+
* generic `data` field — only `message`/`stack`/`cause`/`location`/`snippet`/
|
|
16
|
+
* `value` survive a thrown Error's properties across the worker boundary.
|
|
17
|
+
* `@vgai/probe`'s `ProbeFailure`/`ProbeError` DO carry a rich `.data` object
|
|
18
|
+
* when caught inside the SAME process (see its own `errors.ts`), but that
|
|
19
|
+
* structure is invisible here — `failure-block.ts`'s `assembleFailureBlock`
|
|
20
|
+
* renders the identical eight-member block to BOTH the assertion `message`
|
|
21
|
+
* and its `data` (Task 3.3's contract: "renders... to the assertion message
|
|
22
|
+
* AND as structured data"), so `result.error.message` (or the first of
|
|
23
|
+
* `result.errors`) already contains the full contract text; this reporter
|
|
24
|
+
* treats it as the source of truth rather than reconstructing a lost object.
|
|
25
|
+
* A best-effort `code` is recovered by checking whether the message begins
|
|
26
|
+
* with one of `@vgai/probe`'s frozen error-code tokens (a match on the
|
|
27
|
+
* FROZEN CODE embedded in the message by that package's own `errors.ts`, not
|
|
28
|
+
* a prose heuristic — see `classifyFailureCode`).
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
32
|
+
import { dirname } from 'node:path';
|
|
33
|
+
import type { FullResult, Reporter, TestCase, TestResult } from '@playwright/test/reporter';
|
|
34
|
+
|
|
35
|
+
export const PROBE_REPORT_VERSION = 1 as const;
|
|
36
|
+
|
|
37
|
+
export interface ProbeVerdict {
|
|
38
|
+
title: string;
|
|
39
|
+
file: string;
|
|
40
|
+
line: number;
|
|
41
|
+
status: 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted';
|
|
42
|
+
durationMs: number;
|
|
43
|
+
retry: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ProbeFailureAttachment {
|
|
47
|
+
name: string;
|
|
48
|
+
contentType: string;
|
|
49
|
+
path?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ProbeFailureRecord {
|
|
53
|
+
title: string;
|
|
54
|
+
file: string;
|
|
55
|
+
line: number;
|
|
56
|
+
/** Best-effort, recovered from the frozen code token at the start of the
|
|
57
|
+
* message (see module doc) — `null` when no known token matched (an
|
|
58
|
+
* ordinary `expect()` assertion failure, not a `@vgai/probe` error). */
|
|
59
|
+
code: string | null;
|
|
60
|
+
/** D3: which `GAME_SEAM_NEVER_APPEARED` sub-case this is, recovered the
|
|
61
|
+
* same way (a stable message prefix — see `classifyGameSeamSubCase`).
|
|
62
|
+
* `null` for every other code, including when `code` itself is `null`. */
|
|
63
|
+
subCase: 'page-threw' | 'no-bridge' | null;
|
|
64
|
+
/** The full rendered failure-block text (or plain assertion message) —
|
|
65
|
+
* see the module doc for why this, not a lost `.data` object, is the
|
|
66
|
+
* structured contract this reporter can actually observe. */
|
|
67
|
+
message: string;
|
|
68
|
+
attachments: ProbeFailureAttachment[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface ProbePerfSample {
|
|
72
|
+
title: string;
|
|
73
|
+
wallMs: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface LastRunEnvelope {
|
|
77
|
+
probeReportVersion: 1;
|
|
78
|
+
project: string;
|
|
79
|
+
startedAt: string;
|
|
80
|
+
finishedAt: string;
|
|
81
|
+
status: FullResult['status'];
|
|
82
|
+
verdicts: ProbeVerdict[];
|
|
83
|
+
failures: ProbeFailureRecord[];
|
|
84
|
+
artifacts: { outputDir: string };
|
|
85
|
+
perf: {
|
|
86
|
+
/** Honest-degrade note (never a fabricated fps/sim-speed number): full
|
|
87
|
+
* per-test fps/frame-time-percentile/sim-speed capture needs page-side
|
|
88
|
+
* instrumentation living in `@vgai/probe`'s fixture teardown (a
|
|
89
|
+
* different package/agent's territory) — this reporter can only see
|
|
90
|
+
* Playwright's own wall-clock `duration` per test. */
|
|
91
|
+
note: string;
|
|
92
|
+
samples: ProbePerfSample[];
|
|
93
|
+
};
|
|
94
|
+
/** AC-B1.7 — set ONLY on the synthetic envelope {@link buildWedgeEnvelope}
|
|
95
|
+
* writes when `run-probe.ts`'s `main()` kills the child as a harness
|
|
96
|
+
* wedge (exit 5): this class's `Reporter.onEnd` (the normal writer of
|
|
97
|
+
* this file) never runs in that case — the child is killed mid-suite, not
|
|
98
|
+
* finished — so an ordinary run's envelope never carries this field at
|
|
99
|
+
* all. A consumer (`--last-failure`, a panel, a human `cat`-ing the file)
|
|
100
|
+
* can check this BEFORE trusting `status`/`verdicts`/`failures` as "what
|
|
101
|
+
* actually ran": a wedge envelope's `verdicts`/`failures` are always empty
|
|
102
|
+
* by construction, not because nothing failed. */
|
|
103
|
+
wedged?: true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Frozen error-code tokens `@vgai/probe`'s `errors.ts`/`failure-block.ts`
|
|
107
|
+
* put at the START of a thrown error's message — see the module doc for why
|
|
108
|
+
* matching these specific tokens is not the banned "identify a failure by
|
|
109
|
+
* parsing message prose" pattern (Ground rule 4): it is the one channel
|
|
110
|
+
* through which a frozen `code` survives the Playwright reporter boundary
|
|
111
|
+
* at all. */
|
|
112
|
+
const KNOWN_MESSAGE_CODE_PREFIXES: ReadonlyArray<{ prefix: string; code: string }> = [
|
|
113
|
+
{ prefix: 'PROBE_ENV_MISSING:', code: 'PROBE_ENV_MISSING' },
|
|
114
|
+
{ prefix: 'GAME_SEAM_NEVER_APPEARED:', code: 'GAME_SEAM_NEVER_APPEARED' },
|
|
115
|
+
{ prefix: 'INPUT_GATED:', code: 'INPUT_GATED' },
|
|
116
|
+
{ prefix: 'game.waitFor timed out', code: 'WAIT_FOR_TIMEOUT' },
|
|
117
|
+
{ prefix: 'game.events.expect failed', code: 'EVENTS_EXPECT_FAILED' },
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
/** Strips the assisted-tier warning header (failure-block.ts prepends a line
|
|
121
|
+
* before the headline) so prefix-matching still works on a
|
|
122
|
+
* consumed-assisted-state failure. Shared by `classifyFailureCode` and
|
|
123
|
+
* `classifyGameSeamSubCase`. */
|
|
124
|
+
function stripWarningHeader(message: string): string {
|
|
125
|
+
return message.startsWith('⚠') ? (message.split('\n').slice(1).join('\n') ?? message) : message;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function classifyFailureCode(message: string | undefined): string | null {
|
|
129
|
+
if (!message) return null;
|
|
130
|
+
const withoutWarningHeader = stripWarningHeader(message);
|
|
131
|
+
for (const { prefix, code } of KNOWN_MESSAGE_CODE_PREFIXES) {
|
|
132
|
+
if (withoutWarningHeader.startsWith(prefix)) return code;
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** D3: recovers `GAME_SEAM_NEVER_APPEARED`'s sub-case from the stable message
|
|
138
|
+
* prefix `@vgai/probe`'s `gameSeamNeverAppearedError` embeds (its own
|
|
139
|
+
* `data.subCase` does not survive the Playwright reporter boundary — see
|
|
140
|
+
* this module's doc comment). `null` for any other failure, including a
|
|
141
|
+
* `GAME_SEAM_NEVER_APPEARED` message that somehow carries neither prefix
|
|
142
|
+
* (shouldn't happen — defensive, not silently misclassified as one or the
|
|
143
|
+
* other). */
|
|
144
|
+
export function classifyGameSeamSubCase(
|
|
145
|
+
message: string | undefined,
|
|
146
|
+
): 'page-threw' | 'no-bridge' | null {
|
|
147
|
+
if (!message) return null;
|
|
148
|
+
const withoutWarningHeader = stripWarningHeader(message);
|
|
149
|
+
if (withoutWarningHeader.startsWith('GAME_SEAM_NEVER_APPEARED:page-threw:')) return 'page-threw';
|
|
150
|
+
if (withoutWarningHeader.startsWith('GAME_SEAM_NEVER_APPEARED:no-bridge:')) return 'no-bridge';
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Minimal duck-typed views of Playwright's real `TestCase`/`TestResult` —
|
|
155
|
+
* named separately so unit tests can construct plain fixtures without
|
|
156
|
+
* standing up a real Playwright run (this module's exported pure functions
|
|
157
|
+
* never require the real classes, only these shapes). */
|
|
158
|
+
export interface MinimalTestCase {
|
|
159
|
+
title: string;
|
|
160
|
+
location: { file: string; line: number };
|
|
161
|
+
}
|
|
162
|
+
export interface MinimalTestResult {
|
|
163
|
+
status: 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted';
|
|
164
|
+
duration: number;
|
|
165
|
+
retry: number;
|
|
166
|
+
errors: ReadonlyArray<{ message?: string }>;
|
|
167
|
+
attachments: ReadonlyArray<{ name: string; contentType: string; path?: string }>;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function buildVerdict(test: MinimalTestCase, result: MinimalTestResult): ProbeVerdict {
|
|
171
|
+
return {
|
|
172
|
+
title: test.title,
|
|
173
|
+
file: test.location.file,
|
|
174
|
+
line: test.location.line,
|
|
175
|
+
status: result.status,
|
|
176
|
+
durationMs: result.duration,
|
|
177
|
+
retry: result.retry,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** `null` for a passed/skipped result — only failed/timedOut/interrupted
|
|
182
|
+
* results produce a failure record. */
|
|
183
|
+
export function buildFailureRecord(
|
|
184
|
+
test: MinimalTestCase,
|
|
185
|
+
result: MinimalTestResult,
|
|
186
|
+
): ProbeFailureRecord | null {
|
|
187
|
+
if (result.status === 'passed' || result.status === 'skipped') return null;
|
|
188
|
+
const firstError = result.errors[0];
|
|
189
|
+
const message = firstError?.message ?? `${test.title}: ${result.status} with no captured error`;
|
|
190
|
+
return {
|
|
191
|
+
title: test.title,
|
|
192
|
+
file: test.location.file,
|
|
193
|
+
line: test.location.line,
|
|
194
|
+
code: classifyFailureCode(firstError?.message),
|
|
195
|
+
subCase: classifyGameSeamSubCase(firstError?.message),
|
|
196
|
+
message,
|
|
197
|
+
attachments: result.attachments.map((a) => ({
|
|
198
|
+
name: a.name,
|
|
199
|
+
contentType: a.contentType,
|
|
200
|
+
...(a.path !== undefined ? { path: a.path } : {}),
|
|
201
|
+
})),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface BuildLastRunEnvelopeInput {
|
|
206
|
+
project: string;
|
|
207
|
+
startedAt: string;
|
|
208
|
+
finishedAt: string;
|
|
209
|
+
status: FullResult['status'];
|
|
210
|
+
verdicts: ProbeVerdict[];
|
|
211
|
+
failures: ProbeFailureRecord[];
|
|
212
|
+
outputDir: string;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Task 3.4's exit-code table needs "3 missing capability" distinguished
|
|
216
|
+
* from an ordinary spec failure: true only when EVERY failure in the run
|
|
217
|
+
* is the fixture's own `GAME_SEAM_NEVER_APPEARED` AND its `no-bridge`
|
|
218
|
+
* sub-case (D3) — the page loaded fine but no debug bridge ever appeared.
|
|
219
|
+
* The OTHER sub-case, `page-threw` (the game's own setup code crashed
|
|
220
|
+
* before the bridge could install), is a real spec/build failure and must
|
|
221
|
+
* classify as exit 1, not exit 3 — a mix of either sub-case plus an
|
|
222
|
+
* ordinary assertion failure is likewise a real spec failure (exit 1), not
|
|
223
|
+
* purely a missing capability. */
|
|
224
|
+
export function allFailuresAreMissingCapability(failures: readonly ProbeFailureRecord[]): boolean {
|
|
225
|
+
return (
|
|
226
|
+
failures.length > 0 &&
|
|
227
|
+
failures.every((f) => f.code === 'GAME_SEAM_NEVER_APPEARED' && f.subCase === 'no-bridge')
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function buildLastRunEnvelope(input: BuildLastRunEnvelopeInput): LastRunEnvelope {
|
|
232
|
+
return {
|
|
233
|
+
probeReportVersion: PROBE_REPORT_VERSION,
|
|
234
|
+
project: input.project,
|
|
235
|
+
startedAt: input.startedAt,
|
|
236
|
+
finishedAt: input.finishedAt,
|
|
237
|
+
status: input.status,
|
|
238
|
+
verdicts: input.verdicts,
|
|
239
|
+
failures: input.failures,
|
|
240
|
+
artifacts: { outputDir: input.outputDir },
|
|
241
|
+
perf: {
|
|
242
|
+
note:
|
|
243
|
+
'wall-clock duration only — full fps/frame-time-percentile/sim-speed capture needs ' +
|
|
244
|
+
"page-side instrumentation in @vgai/probe's fixture teardown, not yet wired here.",
|
|
245
|
+
samples: input.verdicts.map((v) => ({ title: v.title, wallMs: v.durationMs })),
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface BuildWedgeEnvelopeInput {
|
|
251
|
+
project: string;
|
|
252
|
+
startedAt: string;
|
|
253
|
+
/** The actual silent-window budget that triggered the kill
|
|
254
|
+
* (`strikeIntervalMs * strikesToWedge`) — see `run-probe.ts`'s
|
|
255
|
+
* `runPlaywrightSuite` doc comment; never hardcoded here so the note below
|
|
256
|
+
* never lies about a test-shrunk budget. */
|
|
257
|
+
wedgeSilenceMs: number;
|
|
258
|
+
outputDir: string;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* AC-B1.7 — the envelope `run-probe.ts`'s `main()` writes to `last-run.json`
|
|
263
|
+
* on a harness wedge (exit 5) INSTEAD of `ProbeJsonReporter.onEnd` (which
|
|
264
|
+
* never runs: the child is killed mid-suite, not finished — see
|
|
265
|
+
* `runPlaywrightSuite`'s `wedgeTriggered` doc comment for the exact
|
|
266
|
+
* mechanics). Without this, `clearStaleLastRun`'s own D4(a) delete (this
|
|
267
|
+
* module's header doc references it) leaves NO `last-run.json` at all after
|
|
268
|
+
* a wedge — a caller reading the file (`--last-failure`, a panel) would see
|
|
269
|
+
* "no file" and have no way to distinguish "no run has ever happened" from
|
|
270
|
+
* "a run just wedged". `verdicts`/`failures` are always empty here — not
|
|
271
|
+
* because nothing failed, but because no test in this run ever reached
|
|
272
|
+
* `onTestEnd` at all; `status: 'interrupted'` is Playwright's own closest
|
|
273
|
+
* documented meaning ("interrupted by the user" — this harness playing that
|
|
274
|
+
* role on the child's behalf), and `wedged: true` is the unambiguous marker
|
|
275
|
+
* a consumer should actually key off rather than inferring intent from
|
|
276
|
+
* `status` prose.
|
|
277
|
+
*/
|
|
278
|
+
export function buildWedgeEnvelope(input: BuildWedgeEnvelopeInput): LastRunEnvelope {
|
|
279
|
+
const silenceSeconds = Math.round(input.wedgeSilenceMs / 1000);
|
|
280
|
+
return {
|
|
281
|
+
probeReportVersion: PROBE_REPORT_VERSION,
|
|
282
|
+
project: input.project,
|
|
283
|
+
startedAt: input.startedAt,
|
|
284
|
+
finishedAt: new Date().toISOString(),
|
|
285
|
+
status: 'interrupted',
|
|
286
|
+
verdicts: [],
|
|
287
|
+
failures: [],
|
|
288
|
+
artifacts: { outputDir: input.outputDir },
|
|
289
|
+
wedged: true,
|
|
290
|
+
perf: {
|
|
291
|
+
note:
|
|
292
|
+
`harness wedge: the child produced no output for ${silenceSeconds}s and was killed ` +
|
|
293
|
+
'(exit 5) before any test reached onTestEnd — there are no verdicts/failures to report ' +
|
|
294
|
+
'from this run; see docs/ACCEPTANCE-DRIVER-SPEC.md §2.2.',
|
|
295
|
+
samples: [],
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export interface ProbeJsonReporterOptions {
|
|
301
|
+
/** Absolute path to write the envelope to (`.vgai/probe/last-run.json`). */
|
|
302
|
+
outputFile: string;
|
|
303
|
+
/** Absolute project directory — carried into the envelope's `project`. */
|
|
304
|
+
projectDir: string;
|
|
305
|
+
/** Absolute artifacts directory (`.vgai/probe/last-run/`) — carried into `artifacts.outputDir`. */
|
|
306
|
+
outputDir: string;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/** The real Playwright-facing reporter — a thin glue layer over the pure
|
|
310
|
+
* functions above. Constructed by Playwright itself via the generated
|
|
311
|
+
* config's `reporter: [[<this module's path>, options]]` entry. */
|
|
312
|
+
export default class ProbeJsonReporter implements Reporter {
|
|
313
|
+
private readonly opts: ProbeJsonReporterOptions;
|
|
314
|
+
private readonly startedAt = new Date().toISOString();
|
|
315
|
+
private verdicts: ProbeVerdict[] = [];
|
|
316
|
+
private failures: ProbeFailureRecord[] = [];
|
|
317
|
+
|
|
318
|
+
constructor(opts: ProbeJsonReporterOptions) {
|
|
319
|
+
this.opts = opts;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
onTestEnd(test: TestCase, result: TestResult): void {
|
|
323
|
+
const minimalTest: MinimalTestCase = { title: test.title, location: test.location };
|
|
324
|
+
const minimalResult: MinimalTestResult = {
|
|
325
|
+
status: result.status,
|
|
326
|
+
duration: result.duration,
|
|
327
|
+
retry: result.retry,
|
|
328
|
+
errors: result.errors,
|
|
329
|
+
attachments: result.attachments,
|
|
330
|
+
};
|
|
331
|
+
this.verdicts.push(buildVerdict(minimalTest, minimalResult));
|
|
332
|
+
const failure = buildFailureRecord(minimalTest, minimalResult);
|
|
333
|
+
if (failure) this.failures.push(failure);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
onEnd(result: FullResult): void {
|
|
337
|
+
const envelope = buildLastRunEnvelope({
|
|
338
|
+
project: this.opts.projectDir,
|
|
339
|
+
startedAt: this.startedAt,
|
|
340
|
+
finishedAt: new Date().toISOString(),
|
|
341
|
+
status: result.status,
|
|
342
|
+
verdicts: this.verdicts,
|
|
343
|
+
failures: this.failures,
|
|
344
|
+
outputDir: this.opts.outputDir,
|
|
345
|
+
});
|
|
346
|
+
mkdirSync(dirname(this.opts.outputFile), { recursive: true });
|
|
347
|
+
writeFileSync(this.opts.outputFile, `${JSON.stringify(envelope, null, 2)}\n`);
|
|
348
|
+
}
|
|
349
|
+
}
|