openvibers/openvibe.games Commits

Run Games' vitest files through test/run.js so ov test can shard them

OP OpenVibers committed 3 Oct 2026 · 1cae50b117 · 101 files, +503 −10

Asked: Follow-up of https://github.com/OpenVibers/openvibe-agents/pull/51 (Refuse bare npm/pnpm whole-suite runs in jobs via a PATH shim): its review asked for a change in OpenVibe.Games that the PR cannot make from openvibe-agents. The review said: VERDICT: FIX
Harness job games-follow-up-of-https-github-com-open-081839.

Changes

ddiff --git a/README.md b/README.md
iindex d7dfdad..443abd5 100644
---- a/README.md
++++ b/README.md
@@@ -92,15 +92,15 @@ freeze. Props are protected: only you and players you trust can move them.
## Commands
--| Command | Purpose |
--| --------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
--| `pnpm dev` | Server + client dev processes in parallel |
--| `pnpm test` | All unit tests (vitest) |
--| `pnpm typecheck` | Strict TypeScript across every package |
--| `pnpm lint` | ESLint (typescript-eslint, no-explicit-any) |
--| `pnpm format` | Prettier write |
--| `pnpm build` | Production build of all packages + client bundle |
--| `tsx apps/server/scripts/sliceTest.ts` | End-to-end vertical-slice test (boots a real server, drives protocol clients, restarts, asserts persistence) |
++| Command | Purpose |
++| -------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
++| `pnpm dev` | Server + client dev processes in parallel |
++| `pnpm test` | All unit tests (vitest, through `test/run.js`) |
++| `pnpm typecheck` | Strict TypeScript across every package |
++| `pnpm lint` | ESLint (typescript-eslint, no-explicit-any) |
++| `pnpm format` | Prettier write |
++| `pnpm build` | Production build of all packages + client bundle |
++| `tsx apps/server/scripts/sliceTest.ts` | End-to-end vertical-slice test (boots a real server, drives protocol clients, restarts, asserts persistence) |
## Production
@@@ -238,6 +238,10 @@ revocation and mod-grant subscriptions), `media.object.upload`
`pnpm test` runs every vitest file (unit tests of the packages and the server, including
`apps/server/src/game/platformIntegration.test.ts`, which boots the real server twice on one database);
++it goes through `test/run.js`, which maps the flat `test/*.test.js` pointers back to the colocated
++TypeScript tests so `ov test` can select and shard them (vitest reads the real files, so their
++`@vitest-environment` docblocks and imports are untouched). After adding or moving a `*.test.ts`,
++run `node test/run.js --index` to regenerate the pointers — a missing or stale pointer fails the run.
`pnpm typecheck` and `pnpm lint` keep strict TypeScript and no `any`;
`tsx apps/server/scripts/sliceTest.ts` drives protocol clients against a real server across a restart.
ddiff --git a/package.json b/package.json
iindex 17de920..ce148b4 100644
---- a/package.json
++++ b/package.json
@@@ -13,7 +13,7 @@
"dev:server": "pnpm --filter @openvibe/server dev",
"dev:client": "pnpm --filter @openvibe/client dev",
"build": "pnpm -r build",
-- "test": "vitest run",
++ "test": "node test/run.js",
"audit:editor": "vitest run --config vitest.audit.config.ts",
"test:editor": "node --import tsx apps/client/e2e/editorCheck.ts",
"test:collab": "node --import tsx apps/client/e2e/editorCollabCheck.ts",
ddiff --git a/test/apps__client__src__editor__architectureAudit.audit.test.js b/test/apps__client__src__editor__architectureAudit.audit.test.js
nnew file mode 100644
iindex 0000000..e3ccec1
---- /dev/null
++++ b/test/apps__client__src__editor__architectureAudit.audit.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/architectureAudit.audit.ts'
++// covers: 'apps/client/src/editor'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__assets__assetController.test.js b/test/apps__client__src__editor__assets__assetController.test.js
nnew file mode 100644
iindex 0000000..951f1f1
---- /dev/null
++++ b/test/apps__client__src__editor__assets__assetController.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/assets/assetController.test.ts'
++// covers: 'apps/client/src/editor/assets'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__bindings.test.js b/test/apps__client__src__editor__bindings.test.js
nnew file mode 100644
iindex 0000000..4609ded
---- /dev/null
++++ b/test/apps__client__src__editor__bindings.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/bindings.test.ts'
++// covers: 'apps/client/src/editor'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__collaboration__lockController.test.js b/test/apps__client__src__editor__collaboration__lockController.test.js
nnew file mode 100644
iindex 0000000..1f44cdf
---- /dev/null
++++ b/test/apps__client__src__editor__collaboration__lockController.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/collaboration/lockController.test.ts'
++// covers: 'apps/client/src/editor/collaboration'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__document__editorDocument.test.js b/test/apps__client__src__editor__document__editorDocument.test.js
nnew file mode 100644
iindex 0000000..45dc119
---- /dev/null
++++ b/test/apps__client__src__editor__document__editorDocument.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/document/editorDocument.test.ts'
++// covers: 'apps/client/src/editor/document'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__document__editorObject.test.js b/test/apps__client__src__editor__document__editorObject.test.js
nnew file mode 100644
iindex 0000000..08da12d
---- /dev/null
++++ b/test/apps__client__src__editor__document__editorObject.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/document/editorObject.test.ts'
++// covers: 'apps/client/src/editor/document'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__history__commandHistory.test.js b/test/apps__client__src__editor__history__commandHistory.test.js
nnew file mode 100644
iindex 0000000..e1ddb5c
---- /dev/null
++++ b/test/apps__client__src__editor__history__commandHistory.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/history/commandHistory.test.ts'
++// covers: 'apps/client/src/editor/history'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__history__commands.test.js b/test/apps__client__src__editor__history__commands.test.js
nnew file mode 100644
iindex 0000000..ef4e492
---- /dev/null
++++ b/test/apps__client__src__editor__history__commands.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/history/commands.test.ts'
++// covers: 'apps/client/src/editor/history'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__input__actionRouter.test.js b/test/apps__client__src__editor__input__actionRouter.test.js
nnew file mode 100644
iindex 0000000..23867fd
---- /dev/null
++++ b/test/apps__client__src__editor__input__actionRouter.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/input/actionRouter.test.ts'
++// covers: 'apps/client/src/editor/input'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__interaction__editorPicker.test.js b/test/apps__client__src__editor__interaction__editorPicker.test.js
nnew file mode 100644
iindex 0000000..83dfaf9
---- /dev/null
++++ b/test/apps__client__src__editor__interaction__editorPicker.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/interaction/editorPicker.test.ts'
++// covers: 'apps/client/src/editor/interaction'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__interaction__interactionController.test.js b/test/apps__client__src__editor__interaction__interactionController.test.js
nnew file mode 100644
iindex 0000000..d530ef8
---- /dev/null
++++ b/test/apps__client__src__editor__interaction__interactionController.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/interaction/interactionController.test.ts'
++// covers: 'apps/client/src/editor/interaction'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__materials__paintableSurface.test.js b/test/apps__client__src__editor__materials__paintableSurface.test.js
nnew file mode 100644
iindex 0000000..d8d7f5f
---- /dev/null
++++ b/test/apps__client__src__editor__materials__paintableSurface.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/materials/paintableSurface.test.ts'
++// covers: 'apps/client/src/editor/materials'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__perf__editorProfiler.test.js b/test/apps__client__src__editor__perf__editorProfiler.test.js
nnew file mode 100644
iindex 0000000..9d15c84
---- /dev/null
++++ b/test/apps__client__src__editor__perf__editorProfiler.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/perf/editorProfiler.test.ts'
++// covers: 'apps/client/src/editor/perf'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__recovery__draftStore.test.js b/test/apps__client__src__editor__recovery__draftStore.test.js
nnew file mode 100644
iindex 0000000..497ff11
---- /dev/null
++++ b/test/apps__client__src__editor__recovery__draftStore.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/recovery/draftStore.test.ts'
++// covers: 'apps/client/src/editor/recovery'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__selection__faceSelection.test.js b/test/apps__client__src__editor__selection__faceSelection.test.js
nnew file mode 100644
iindex 0000000..876fadd
---- /dev/null
++++ b/test/apps__client__src__editor__selection__faceSelection.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/selection/faceSelection.test.ts'
++// covers: 'apps/client/src/editor/selection'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__selection__selectionManager.test.js b/test/apps__client__src__editor__selection__selectionManager.test.js
nnew file mode 100644
iindex 0000000..478e263
---- /dev/null
++++ b/test/apps__client__src__editor__selection__selectionManager.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/selection/selectionManager.test.ts'
++// covers: 'apps/client/src/editor/selection'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__tools__lightZoneTool.test.js b/test/apps__client__src__editor__tools__lightZoneTool.test.js
nnew file mode 100644
iindex 0000000..9e2867a
---- /dev/null
++++ b/test/apps__client__src__editor__tools__lightZoneTool.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/tools/lightZoneTool.test.ts'
++// covers: 'apps/client/src/editor/tools'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__tools__terrainTool.test.js b/test/apps__client__src__editor__tools__terrainTool.test.js
nnew file mode 100644
iindex 0000000..2d827a7
---- /dev/null
++++ b/test/apps__client__src__editor__tools__terrainTool.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/tools/terrainTool.test.ts'
++// covers: 'apps/client/src/editor/tools'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__tools__toolManager.test.js b/test/apps__client__src__editor__tools__toolManager.test.js
nnew file mode 100644
iindex 0000000..ff1c791
---- /dev/null
++++ b/test/apps__client__src__editor__tools__toolManager.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/tools/toolManager.test.ts'
++// covers: 'apps/client/src/editor/tools'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__ui__inspector.test.js b/test/apps__client__src__editor__ui__inspector.test.js
nnew file mode 100644
iindex 0000000..0671f3f
---- /dev/null
++++ b/test/apps__client__src__editor__ui__inspector.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/ui/inspector.test.ts'
++// covers: 'apps/client/src/editor/ui'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__ui__numberField.test.js b/test/apps__client__src__editor__ui__numberField.test.js
nnew file mode 100644
iindex 0000000..b083de2
---- /dev/null
++++ b/test/apps__client__src__editor__ui__numberField.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/ui/numberField.test.ts'
++// covers: 'apps/client/src/editor/ui'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__ui__outliner.test.js b/test/apps__client__src__editor__ui__outliner.test.js
nnew file mode 100644
iindex 0000000..1d70543
---- /dev/null
++++ b/test/apps__client__src__editor__ui__outliner.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/ui/outliner.test.ts'
++// covers: 'apps/client/src/editor/ui'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__ui__panels.test.js b/test/apps__client__src__editor__ui__panels.test.js
nnew file mode 100644
iindex 0000000..d3a55b9
---- /dev/null
++++ b/test/apps__client__src__editor__ui__panels.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/ui/panels.test.ts'
++// covers: 'apps/client/src/editor/ui'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__viewport__editorPreferences.test.js b/test/apps__client__src__editor__viewport__editorPreferences.test.js
nnew file mode 100644
iindex 0000000..4f2a874
---- /dev/null
++++ b/test/apps__client__src__editor__viewport__editorPreferences.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/viewport/editorPreferences.test.ts'
++// covers: 'apps/client/src/editor/viewport'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__viewport__editorViewRegistry.test.js b/test/apps__client__src__editor__viewport__editorViewRegistry.test.js
nnew file mode 100644
iindex 0000000..80a761c
---- /dev/null
++++ b/test/apps__client__src__editor__viewport__editorViewRegistry.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/viewport/editorViewRegistry.test.ts'
++// covers: 'apps/client/src/editor/viewport'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__viewport__transformMath.test.js b/test/apps__client__src__editor__viewport__transformMath.test.js
nnew file mode 100644
iindex 0000000..9170f89
---- /dev/null
++++ b/test/apps__client__src__editor__viewport__transformMath.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/viewport/transformMath.test.ts'
++// covers: 'apps/client/src/editor/viewport'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__editor__viewport__transformSession.test.js b/test/apps__client__src__editor__viewport__transformSession.test.js
nnew file mode 100644
iindex 0000000..e606191
---- /dev/null
++++ b/test/apps__client__src__editor__viewport__transformSession.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/editor/viewport/transformSession.test.ts'
++// covers: 'apps/client/src/editor/viewport'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__input__inputSource.test.js b/test/apps__client__src__input__inputSource.test.js
nnew file mode 100644
iindex 0000000..3405cc2
---- /dev/null
++++ b/test/apps__client__src__input__inputSource.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/input/inputSource.test.ts'
++// covers: 'apps/client/src/input'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__pages__pageIcon.test.js b/test/apps__client__src__pages__pageIcon.test.js
nnew file mode 100644
iindex 0000000..cca12f2
---- /dev/null
++++ b/test/apps__client__src__pages__pageIcon.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/pages/pageIcon.test.ts'
++// covers: 'apps/client/src/pages'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__client__src__render__paintedStatic.test.js b/test/apps__client__src__render__paintedStatic.test.js
nnew file mode 100644
iindex 0000000..95ebdea
---- /dev/null
++++ b/test/apps__client__src__render__paintedStatic.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/client/src/render/paintedStatic.test.ts'
++// covers: 'apps/client/src/render'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__scripts__deployWrapper.test.js b/test/apps__server__scripts__deployWrapper.test.js
nnew file mode 100644
iindex 0000000..6508a8b
---- /dev/null
++++ b/test/apps__server__scripts__deployWrapper.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/scripts/deployWrapper.test.ts'
++// covers: 'apps/server/scripts'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__architectureAudit.audit.test.js b/test/apps__server__src__architectureAudit.audit.test.js
nnew file mode 100644
iindex 0000000..3194d57
---- /dev/null
++++ b/test/apps__server__src__architectureAudit.audit.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/architectureAudit.audit.ts'
++// covers: 'apps/server/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__config.test.js b/test/apps__server__src__config.test.js
nnew file mode 100644
iindex 0000000..d89d4bd
---- /dev/null
++++ b/test/apps__server__src__config.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/config.test.ts'
++// covers: 'apps/server/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__game__flusher.test.js b/test/apps__server__src__game__flusher.test.js
nnew file mode 100644
iindex 0000000..a1ebc67
---- /dev/null
++++ b/test/apps__server__src__game__flusher.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/game/flusher.test.ts'
++// covers: 'apps/server/src/game'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__game__handlerTable.test.js b/test/apps__server__src__game__handlerTable.test.js
nnew file mode 100644
iindex 0000000..d59f3c1
---- /dev/null
++++ b/test/apps__server__src__game__handlerTable.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/game/handlerTable.test.ts'
++// covers: 'apps/server/src/game'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__game__mapProvenance.test.js b/test/apps__server__src__game__mapProvenance.test.js
nnew file mode 100644
iindex 0000000..6bec195
---- /dev/null
++++ b/test/apps__server__src__game__mapProvenance.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/game/mapProvenance.test.ts'
++// covers: 'apps/server/src/game'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__game__mapStaticLayer.test.js b/test/apps__server__src__game__mapStaticLayer.test.js
nnew file mode 100644
iindex 0000000..b5cba9b
---- /dev/null
++++ b/test/apps__server__src__game__mapStaticLayer.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/game/mapStaticLayer.test.ts'
++// covers: 'apps/server/src/game'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__game__mapTerrainLayer.test.js b/test/apps__server__src__game__mapTerrainLayer.test.js
nnew file mode 100644
iindex 0000000..89497a0
---- /dev/null
++++ b/test/apps__server__src__game__mapTerrainLayer.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/game/mapTerrainLayer.test.ts'
++// covers: 'apps/server/src/game'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__game__platformIntegration.test.js b/test/apps__server__src__game__platformIntegration.test.js
nnew file mode 100644
iindex 0000000..69e661e
---- /dev/null
++++ b/test/apps__server__src__game__platformIntegration.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/game/platformIntegration.test.ts'
++// covers: 'apps/server/src/game'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__mods__manifest.test.js b/test/apps__server__src__mods__manifest.test.js
nnew file mode 100644
iindex 0000000..50b3b90
---- /dev/null
++++ b/test/apps__server__src__mods__manifest.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/mods/manifest.test.ts'
++// covers: 'apps/server/src/mods'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__mods__moderationEvents.test.js b/test/apps__server__src__mods__moderationEvents.test.js
nnew file mode 100644
iindex 0000000..d7117d8
---- /dev/null
++++ b/test/apps__server__src__mods__moderationEvents.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/mods/moderationEvents.test.ts'
++// covers: 'apps/server/src/mods'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__mods__networkGrants.test.js b/test/apps__server__src__mods__networkGrants.test.js
nnew file mode 100644
iindex 0000000..861eb76
---- /dev/null
++++ b/test/apps__server__src__mods__networkGrants.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/mods/networkGrants.test.ts'
++// covers: 'apps/server/src/mods'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__mods__routes.test.js b/test/apps__server__src__mods__routes.test.js
nnew file mode 100644
iindex 0000000..10f2c69
---- /dev/null
++++ b/test/apps__server__src__mods__routes.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/mods/routes.test.ts'
++// covers: 'apps/server/src/mods'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__mods__runtime.test.js b/test/apps__server__src__mods__runtime.test.js
nnew file mode 100644
iindex 0000000..db6bee7
---- /dev/null
++++ b/test/apps__server__src__mods__runtime.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/mods/runtime.test.ts'
++// covers: 'apps/server/src/mods'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__mods__security.test.js b/test/apps__server__src__mods__security.test.js
nnew file mode 100644
iindex 0000000..1373021
---- /dev/null
++++ b/test/apps__server__src__mods__security.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/mods/security.test.ts'
++// covers: 'apps/server/src/mods'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__actorLimits.test.js b/test/apps__server__src__net__actorLimits.test.js
nnew file mode 100644
iindex 0000000..1bcdc75
---- /dev/null
++++ b/test/apps__server__src__net__actorLimits.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/actorLimits.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__clientAddress.test.js b/test/apps__server__src__net__clientAddress.test.js
nnew file mode 100644
iindex 0000000..993b0f3
---- /dev/null
++++ b/test/apps__server__src__net__clientAddress.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/clientAddress.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__discovery.test.js b/test/apps__server__src__net__discovery.test.js
nnew file mode 100644
iindex 0000000..7250935
---- /dev/null
++++ b/test/apps__server__src__net__discovery.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/discovery.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__editorLocks.test.js b/test/apps__server__src__net__editorLocks.test.js
nnew file mode 100644
iindex 0000000..6b8866e
---- /dev/null
++++ b/test/apps__server__src__net__editorLocks.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/editorLocks.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__httpServer.test.js b/test/apps__server__src__net__httpServer.test.js
nnew file mode 100644
iindex 0000000..cc01968
---- /dev/null
++++ b/test/apps__server__src__net__httpServer.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/httpServer.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__legalPages.test.js b/test/apps__server__src__net__legalPages.test.js
nnew file mode 100644
iindex 0000000..0338fdd
---- /dev/null
++++ b/test/apps__server__src__net__legalPages.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/legalPages.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__mapAssetStore.test.js b/test/apps__server__src__net__mapAssetStore.test.js
nnew file mode 100644
iindex 0000000..09243d8
---- /dev/null
++++ b/test/apps__server__src__net__mapAssetStore.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/mapAssetStore.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__mapStore.test.js b/test/apps__server__src__net__mapStore.test.js
nnew file mode 100644
iindex 0000000..59c1006
---- /dev/null
++++ b/test/apps__server__src__net__mapStore.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/mapStore.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__networkAuth.test.js b/test/apps__server__src__net__networkAuth.test.js
nnew file mode 100644
iindex 0000000..539ad85
---- /dev/null
++++ b/test/apps__server__src__net__networkAuth.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/networkAuth.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__sharedAssets.test.js b/test/apps__server__src__net__sharedAssets.test.js
nnew file mode 100644
iindex 0000000..b4b8751
---- /dev/null
++++ b/test/apps__server__src__net__sharedAssets.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/sharedAssets.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__sso.test.js b/test/apps__server__src__net__sso.test.js
nnew file mode 100644
iindex 0000000..a1f800f
---- /dev/null
++++ b/test/apps__server__src__net__sso.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/sso.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__staffAuthorization.test.js b/test/apps__server__src__net__staffAuthorization.test.js
nnew file mode 100644
iindex 0000000..654234e
---- /dev/null
++++ b/test/apps__server__src__net__staffAuthorization.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/staffAuthorization.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__wsTicket.test.js b/test/apps__server__src__net__wsTicket.test.js
nnew file mode 100644
iindex 0000000..eb65202
---- /dev/null
++++ b/test/apps__server__src__net__wsTicket.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/wsTicket.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__wsTicketEndpoint.test.js b/test/apps__server__src__net__wsTicketEndpoint.test.js
nnew file mode 100644
iindex 0000000..c9c4881
---- /dev/null
++++ b/test/apps__server__src__net__wsTicketEndpoint.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/wsTicketEndpoint.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__net__wsTransport.test.js b/test/apps__server__src__net__wsTransport.test.js
nnew file mode 100644
iindex 0000000..065505f
---- /dev/null
++++ b/test/apps__server__src__net__wsTransport.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/net/wsTransport.test.ts'
++// covers: 'apps/server/src/net'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__observability__readiness.test.js b/test/apps__server__src__observability__readiness.test.js
nnew file mode 100644
iindex 0000000..7e27fca
---- /dev/null
++++ b/test/apps__server__src__observability__readiness.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/observability/readiness.test.ts'
++// covers: 'apps/server/src/observability'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__observability__release.test.js b/test/apps__server__src__observability__release.test.js
nnew file mode 100644
iindex 0000000..0c49c3d
---- /dev/null
++++ b/test/apps__server__src__observability__release.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/observability/release.test.ts'
++// covers: 'apps/server/src/observability'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__accountData.test.js b/test/apps__server__src__platform__accountData.test.js
nnew file mode 100644
iindex 0000000..d3f3754
---- /dev/null
++++ b/test/apps__server__src__platform__accountData.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/accountData.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__accounts.test.js b/test/apps__server__src__platform__accounts.test.js
nnew file mode 100644
iindex 0000000..8bb64aa
---- /dev/null
++++ b/test/apps__server__src__platform__accounts.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/accounts.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__gameEvents.test.js b/test/apps__server__src__platform__gameEvents.test.js
nnew file mode 100644
iindex 0000000..14bccde
---- /dev/null
++++ b/test/apps__server__src__platform__gameEvents.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/gameEvents.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__mediaMirror.test.js b/test/apps__server__src__platform__mediaMirror.test.js
nnew file mode 100644
iindex 0000000..c048688
---- /dev/null
++++ b/test/apps__server__src__platform__mediaMirror.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/mediaMirror.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__progressSummary.test.js b/test/apps__server__src__platform__progressSummary.test.js
nnew file mode 100644
iindex 0000000..8ffaa68
---- /dev/null
++++ b/test/apps__server__src__platform__progressSummary.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/progressSummary.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__proposals.test.js b/test/apps__server__src__platform__proposals.test.js
nnew file mode 100644
iindex 0000000..6fb9963
---- /dev/null
++++ b/test/apps__server__src__platform__proposals.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/proposals.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__revocationEvents.test.js b/test/apps__server__src__platform__revocationEvents.test.js
nnew file mode 100644
iindex 0000000..5197d36
---- /dev/null
++++ b/test/apps__server__src__platform__revocationEvents.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/revocationEvents.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__platform__staffAuth.test.js b/test/apps__server__src__platform__staffAuth.test.js
nnew file mode 100644
iindex 0000000..cc8fe1f
---- /dev/null
++++ b/test/apps__server__src__platform__staffAuth.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/platform/staffAuth.test.ts'
++// covers: 'apps/server/src/platform'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/apps__server__src__shutdown.test.js b/test/apps__server__src__shutdown.test.js
nnew file mode 100644
iindex 0000000..85c8752
---- /dev/null
++++ b/test/apps__server__src__shutdown.test.js
@@@ -0,0 +1,3 @@
++// file: 'apps/server/src/shutdown.test.ts'
++// covers: 'apps/server/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__content__src__mapDiff.test.js b/test/packages__content__src__mapDiff.test.js
nnew file mode 100644
iindex 0000000..8789975
---- /dev/null
++++ b/test/packages__content__src__mapDiff.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/content/src/mapDiff.test.ts'
++// covers: 'packages/content/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__content__src__mapFileV2.test.js b/test/packages__content__src__mapFileV2.test.js
nnew file mode 100644
iindex 0000000..27449a5
---- /dev/null
++++ b/test/packages__content__src__mapFileV2.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/content/src/mapFileV2.test.ts'
++// covers: 'packages/content/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__content__src__surface.test.js b/test/packages__content__src__surface.test.js
nnew file mode 100644
iindex 0000000..bcecd44
---- /dev/null
++++ b/test/packages__content__src__surface.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/content/src/surface.test.ts'
++// covers: 'packages/content/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__combat__damage.test.js b/test/packages__gameplay__src__combat__damage.test.js
nnew file mode 100644
iindex 0000000..273ea4e
---- /dev/null
++++ b/test/packages__gameplay__src__combat__damage.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/combat/damage.test.ts'
++// covers: 'packages/gameplay/src/combat'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__constraints__constraints.test.js b/test/packages__gameplay__src__constraints__constraints.test.js
nnew file mode 100644
iindex 0000000..863a1f9
---- /dev/null
++++ b/test/packages__gameplay__src__constraints__constraints.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/constraints/constraints.test.ts'
++// covers: 'packages/gameplay/src/constraints'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__constraints__islands.test.js b/test/packages__gameplay__src__constraints__islands.test.js
nnew file mode 100644
iindex 0000000..3b55ebf
---- /dev/null
++++ b/test/packages__gameplay__src__constraints__islands.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/constraints/islands.test.ts'
++// covers: 'packages/gameplay/src/constraints'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__containers__containers.test.js b/test/packages__gameplay__src__containers__containers.test.js
nnew file mode 100644
iindex 0000000..7642ab5
---- /dev/null
++++ b/test/packages__gameplay__src__containers__containers.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/containers/containers.test.ts'
++// covers: 'packages/gameplay/src/containers'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__crafting__crafting.test.js b/test/packages__gameplay__src__crafting__crafting.test.js
nnew file mode 100644
iindex 0000000..c20dcd8
---- /dev/null
++++ b/test/packages__gameplay__src__crafting__crafting.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/crafting/crafting.test.ts'
++// covers: 'packages/gameplay/src/crafting'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__environment__environment.test.js b/test/packages__gameplay__src__environment__environment.test.js
nnew file mode 100644
iindex 0000000..3dfc396
---- /dev/null
++++ b/test/packages__gameplay__src__environment__environment.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/environment/environment.test.ts'
++// covers: 'packages/gameplay/src/environment'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__farming__farming.test.js b/test/packages__gameplay__src__farming__farming.test.js
nnew file mode 100644
iindex 0000000..d1729e6
---- /dev/null
++++ b/test/packages__gameplay__src__farming__farming.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/farming/farming.test.ts'
++// covers: 'packages/gameplay/src/farming'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__inventory__inventory.test.js b/test/packages__gameplay__src__inventory__inventory.test.js
nnew file mode 100644
iindex 0000000..6ac3e41
---- /dev/null
++++ b/test/packages__gameplay__src__inventory__inventory.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/inventory/inventory.test.ts'
++// covers: 'packages/gameplay/src/inventory'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__machines__machines.test.js b/test/packages__gameplay__src__machines__machines.test.js
nnew file mode 100644
iindex 0000000..e14218c
---- /dev/null
++++ b/test/packages__gameplay__src__machines__machines.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/machines/machines.test.ts'
++// covers: 'packages/gameplay/src/machines'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__movement__determinism.test.js b/test/packages__gameplay__src__movement__determinism.test.js
nnew file mode 100644
iindex 0000000..cfb9bf0
---- /dev/null
++++ b/test/packages__gameplay__src__movement__determinism.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/movement/determinism.test.ts'
++// covers: 'packages/gameplay/src/movement'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__movement__simulate.test.js b/test/packages__gameplay__src__movement__simulate.test.js
nnew file mode 100644
iindex 0000000..e9e5905
---- /dev/null
++++ b/test/packages__gameplay__src__movement__simulate.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/movement/simulate.test.ts'
++// covers: 'packages/gameplay/src/movement'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__npc__npc.test.js b/test/packages__gameplay__src__npc__npc.test.js
nnew file mode 100644
iindex 0000000..7b49e5b
---- /dev/null
++++ b/test/packages__gameplay__src__npc__npc.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/npc/npc.test.ts'
++// covers: 'packages/gameplay/src/npc'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__skills__skills.test.js b/test/packages__gameplay__src__skills__skills.test.js
nnew file mode 100644
iindex 0000000..78bfe30
---- /dev/null
++++ b/test/packages__gameplay__src__skills__skills.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/skills/skills.test.ts'
++// covers: 'packages/gameplay/src/skills'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__spatial__spatialHash.test.js b/test/packages__gameplay__src__spatial__spatialHash.test.js
nnew file mode 100644
iindex 0000000..bb23249
---- /dev/null
++++ b/test/packages__gameplay__src__spatial__spatialHash.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/spatial/spatialHash.test.ts'
++// covers: 'packages/gameplay/src/spatial'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__survival__survival.test.js b/test/packages__gameplay__src__survival__survival.test.js
nnew file mode 100644
iindex 0000000..394bc35
---- /dev/null
++++ b/test/packages__gameplay__src__survival__survival.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/survival/survival.test.ts'
++// covers: 'packages/gameplay/src/survival'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__gameplay__src__zones__zones.test.js b/test/packages__gameplay__src__zones__zones.test.js
nnew file mode 100644
iindex 0000000..b6e9c37
---- /dev/null
++++ b/test/packages__gameplay__src__zones__zones.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/gameplay/src/zones/zones.test.ts'
++// covers: 'packages/gameplay/src/zones'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__persistence__src__accountKey.test.js b/test/packages__persistence__src__accountKey.test.js
nnew file mode 100644
iindex 0000000..0f6074b
---- /dev/null
++++ b/test/packages__persistence__src__accountKey.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/persistence/src/accountKey.test.ts'
++// covers: 'packages/persistence/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__persistence__src__pg__pgStore.test.js b/test/packages__persistence__src__pg__pgStore.test.js
nnew file mode 100644
iindex 0000000..bdcc9c8
---- /dev/null
++++ b/test/packages__persistence__src__pg__pgStore.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/persistence/src/pg/pgStore.test.ts'
++// covers: 'packages/persistence/src/pg'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__persistence__src__pg__platformRepositories.test.js b/test/packages__persistence__src__pg__platformRepositories.test.js
nnew file mode 100644
iindex 0000000..df99a2c
---- /dev/null
++++ b/test/packages__persistence__src__pg__platformRepositories.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/persistence/src/pg/platformRepositories.test.ts'
++// covers: 'packages/persistence/src/pg'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__physics__src__conformance.test.js b/test/packages__physics__src__conformance.test.js
nnew file mode 100644
iindex 0000000..dde2873
---- /dev/null
++++ b/test/packages__physics__src__conformance.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/physics/src/conformance.test.ts'
++// covers: 'packages/physics/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__protocol__src__codec.test.js b/test/packages__protocol__src__codec.test.js
nnew file mode 100644
iindex 0000000..7da39d1
---- /dev/null
++++ b/test/packages__protocol__src__codec.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/protocol/src/codec.test.ts'
++// covers: 'packages/protocol/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__protocol__src__editor.test.js b/test/packages__protocol__src__editor.test.js
nnew file mode 100644
iindex 0000000..dbd35f7
---- /dev/null
++++ b/test/packages__protocol__src__editor.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/protocol/src/editor.test.ts'
++// covers: 'packages/protocol/src'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__shared__src__math__quat.test.js b/test/packages__shared__src__math__quat.test.js
nnew file mode 100644
iindex 0000000..2478c73
---- /dev/null
++++ b/test/packages__shared__src__math__quat.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/shared/src/math/quat.test.ts'
++// covers: 'packages/shared/src/math'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/packages__shared__src__math__scalar.test.js b/test/packages__shared__src__math__scalar.test.js
nnew file mode 100644
iindex 0000000..fc19515
---- /dev/null
++++ b/test/packages__shared__src__math__scalar.test.js
@@@ -0,0 +1,3 @@
++// file: 'packages/shared/src/math/scalar.test.ts'
++// covers: 'packages/shared/src/math'
++// Generated by node test/run.js --index; do not edit.
ddiff --git a/test/run.js b/test/run.js
nnew file mode 100644
iindex 0000000..c1263b0
---- /dev/null
++++ b/test/run.js
@@@ -0,0 +1,195 @@
++#!/usr/bin/env node
++// test/run.js — Games' own test runner, the shape `ov test` drives. ds-testsel calls
++// `node test/run.js <test/… entries>`; each entry under test/ is a one-line pointer to a
++// colocated TypeScript test, and this runs those through vitest and prints the per-file lines
++// ov test parses (✓/✗ <entry> <ms>ms). With no argument it runs every vitest file (`pnpm test`).
++//
++// The pointers exist because Games' tests are TypeScript and colocated, not the test/*.test.js
++// files the harness's runner convention expects; vitest reads the real files, so their
++// @vitest-environment docblocks and imports stay exactly as written. The pointers are generated
++// from the vitest include globs by `node test/run.js --index`; a missing or stale one fails the
++// run rather than silently testing less.
++//
++// node test/run.js every test file
++// node test/run.js <entry|word>… the entries whose name matches a word
++// node test/run.js --index (re)write the test/ pointers from the vitest include globs
++import { spawnSync } from 'node:child_process'
++import {
++ existsSync,
++ mkdtempSync,
++ readdirSync,
++ readFileSync,
++ rmSync,
++ unlinkSync,
++ writeFileSync,
++} from 'node:fs'
++import { tmpdir } from 'node:os'
++import path from 'node:path'
++import { fileURLToPath } from 'node:url'
++
++const dir = path.dirname(fileURLToPath(import.meta.url))
++const root = path.join(dir, '..')
++const POINTER = /^\/\/ file: '(.+)'$/m
++
++/** Every file vitest.config.ts runs: the .test.ts and .audit.ts files under apps and packages. */
++function vitestFiles() {
++ const out = []
++ const walk = (rel) => {
++ for (const e of readdirSync(path.join(root, rel), { withFileTypes: true })) {
++ if (e.name === 'node_modules' || e.name === 'dist' || e.name === 'dist-types') continue
++ const r = `${rel}/${e.name}`
++ if (e.isDirectory()) walk(r)
++ else if (/\.(test|audit)\.ts$/.test(e.name)) out.push(r)
++ }
++ }
++ for (const top of ['apps', 'packages']) if (existsSync(path.join(root, top))) walk(top)
++ return out.sort()
++}
++
++/** test/<slug>.test.js for a TypeScript test: flat, so ds-testsel can list and shard them. */
++function pointerName(ts) {
++ const stem = ts.replace(/\.ts$/, '')
++ return `${stem}${stem.endsWith('.test') ? '.js' : '.test.js'}`.replace(/\//g, '__')
++}
++
++/** The pointers in test/: entry basename → the TypeScript file it runs. */
++function pointers() {
++ const map = new Map()
++ for (const f of readdirSync(dir).filter((f) => f.endsWith('.test.js'))) {
++ const m = POINTER.exec(readFileSync(path.join(dir, f), 'utf8'))
++ if (m) map.set(f, m[1].trim())
++ }
++ return map
++}
++
++/** Exactly one pointer per vitest file; drift fails the run rather than silently testing less. */
++function check(ents, files) {
++ const byTs = new Map([...ents].map(([f, ts]) => [ts, f]))
++ const missing = files.filter((ts) => !byTs.has(ts))
++ const stale = [...ents].filter(([, ts]) => !files.includes(ts))
++ if (!missing.length && !stale.length) return true
++ for (const ts of missing) {
++ console.error(`test/run.js: no test/ pointer for ${ts} — run \`node test/run.js --index\``)
++ }
++ for (const [f, ts] of stale) {
++ console.error(
++ `test/run.js: ${f} points at ${ts}, which vitest no longer runs — run \`node test/run.js --index\``,
++ )
++ }
++ return false
++}
++
++function index() {
++ const files = vitestFiles()
++ const want = new Map(files.map((ts) => [pointerName(ts), ts]))
++ if (want.size !== files.length) {
++ console.error('test/run.js: two test paths map to the same pointer name; rename one')
++ process.exit(1)
++ }
++ // The `covers:` line is quoted so ds-testsel's path-based selection (a change in the test's own
++ // directory) reaches the pointer even when the source file's name does not match the test's.
++ const body = (ts) =>
++ `// file: '${ts}'\n// covers: '${path.posix.dirname(ts)}'\n// Generated by node test/run.js --index; do not edit.\n`
++ for (const [name, ts] of want) {
++ const p = path.join(dir, name)
++ if (!existsSync(p) || readFileSync(p, 'utf8') !== body(ts)) writeFileSync(p, body(ts))
++ }
++ let removed = 0
++ for (const f of readdirSync(dir)) {
++ if (!f.endsWith('.test.js') || want.has(f)) continue
++ if (POINTER.exec(readFileSync(path.join(dir, f), 'utf8'))) {
++ unlinkSync(path.join(dir, f))
++ removed++
++ }
++ }
++ console.log(
++ `test/run.js: ${want.size} pointers written${removed ? `, ${removed} stale removed` : ''}`,
++ )
++}
++
++const argv = process.argv.slice(2)
++if (argv.includes('--index')) {
++ index()
++ process.exit(0)
++}
++
++const ents = pointers()
++const files = vitestFiles()
++if (!check(ents, files)) process.exit(1)
++
++const words = argv.filter((a) => !a.startsWith('--'))
++let chosen
++if (!words.length) {
++ chosen = [...ents.keys()]
++} else {
++ const set = new Set()
++ for (const w of words) {
++ const base = path.basename(w)
++ if (ents.has(base)) {
++ set.add(base)
++ continue
++ }
++ const hits = [...ents.keys()].filter(
++ (f) => f.includes(base) || f.includes(base.replace(/\.test\.js$/, '')),
++ )
++ if (!hits.length) {
++ console.error(`test/run.js: no test/ pointer matches ${w}`)
++ process.exit(1)
++ }
++ for (const h of hits) set.add(h)
++ }
++ chosen = [...set]
++}
++
++const vitest = path.join(root, 'node_modules', '.bin', 'vitest')
++if (!existsSync(vitest)) {
++ console.error('test/run.js: vitest is not installed — run `pnpm install`')
++ process.exit(127)
++}
++
++const tsFiles = [...new Set(chosen.map((f) => ents.get(f)))].sort()
++const tmp = mkdtempSync(path.join(tmpdir(), 'ov-games-test-'))
++const reportFile = path.join(tmp, 'report.json')
++const r = spawnSync(vitest, ['run', '--reporter=json', `--outputFile=${reportFile}`, ...tsFiles], {
++ cwd: root,
++ stdio: ['ignore', 'pipe', 'pipe'],
++})
++const vitestOut = `${r.stdout || ''}${r.stderr || ''}`.trim()
++let report = null
++try {
++ report = JSON.parse(readFileSync(reportFile, 'utf8'))
++} catch {
++ // vitest died before writing the report; the captured output below says why
++}
++rmSync(tmp, { recursive: true, force: true })
++
++const byAbs = new Map()
++for (const t of (report && report.testResults) || []) byAbs.set(path.resolve(t.name), t)
++
++const tails = []
++let bad = 0
++for (const f of chosen) {
++ const ts = ents.get(f)
++ const t = byAbs.get(path.resolve(root, ts))
++ const failed =
++ !t || t.status === 'failed' || (t.assertionResults || []).some((a) => a.status === 'failed')
++ const ms = t && t.endTime != null ? Math.max(0, Math.round(t.endTime - t.startTime)) : 0
++ console.log(`${failed ? '✗' : '✓'} ${f} ${ms}ms`)
++ if (!failed) continue
++ bad++
++ const detail = !t
++ ? `no vitest result for ${ts}${r.status ? ` (vitest exited ${r.status})` : ''}\n${vitestOut
++ .split('\n')
++ .slice(-15)
++ .join('\n')}`
++ : (t.assertionResults || [])
++ .filter((a) => a.status === 'failed')
++ .map((a) => (a.failureMessages || []).join('\n'))
++ .filter(Boolean)
++ .join('\n') ||
++ t.message ||
++ 'failed'
++ tails.push(`── ${f} (exit 1) ──\n${detail}`)
++}
++for (const tail of tails) console.log(`\n${tail}`)
++process.exit(bad ? 1 : 0)