@dreamboard-games/cli 0.1.30-alpha.4 → 0.1.30-alpha.40
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 +32 -113
- package/dist/agent-verifier/agent-workspace-verifier.mjs +2084 -57
- package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -1
- package/dist/agent-verifier/{chunk-XQXDOBYB.mjs → chunk-4I2WWAPK.mjs} +27 -10
- package/dist/agent-verifier/chunk-4I2WWAPK.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-C3VW3DTA.mjs → chunk-BWBN2TDJ.mjs} +535 -633
- package/dist/agent-verifier/chunk-BWBN2TDJ.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-TAEQKBJB.mjs → chunk-GWRZRWCF.mjs} +1 -1
- package/dist/agent-verifier/chunk-GWRZRWCF.mjs.map +1 -0
- package/dist/agent-verifier/chunk-HUBV22JQ.mjs +89 -0
- package/dist/agent-verifier/chunk-HUBV22JQ.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-MW2QIWWA.mjs → chunk-KAA3B4DI.mjs} +215 -223
- package/dist/agent-verifier/chunk-KAA3B4DI.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-27EEIZCI.mjs → chunk-KDAQ4CZY.mjs} +34 -27
- package/dist/agent-verifier/chunk-KDAQ4CZY.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-IAYRNVUC.mjs → chunk-LMW66VBH.mjs} +2 -13
- package/dist/agent-verifier/{chunk-IAYRNVUC.mjs.map → chunk-LMW66VBH.mjs.map} +1 -1
- package/dist/agent-verifier/{chunk-776W3UGV.mjs → chunk-LROY5SN2.mjs} +7 -45
- package/dist/agent-verifier/chunk-LROY5SN2.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-H76MT5UR.mjs → chunk-M7UVBANQ.mjs} +2 -1
- package/dist/agent-verifier/chunk-M7UVBANQ.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-5NYBTZB4.mjs → chunk-MIRGCMUC.mjs} +112 -26
- package/dist/agent-verifier/chunk-MIRGCMUC.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-NAK77WXW.mjs → chunk-MYMVXTZT.mjs} +4 -5
- package/dist/agent-verifier/chunk-MYMVXTZT.mjs.map +1 -0
- package/dist/agent-verifier/chunk-OJFZVGEL.mjs +492 -0
- package/dist/agent-verifier/chunk-OJFZVGEL.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-XKCJBIRY.mjs → chunk-QD4SQNUP.mjs} +2 -2
- package/dist/agent-verifier/{chunk-QBAF7EYR.mjs → chunk-TTB7AIHZ.mjs} +4 -4
- package/dist/agent-verifier/{chunk-QBAF7EYR.mjs.map → chunk-TTB7AIHZ.mjs.map} +1 -1
- package/dist/agent-verifier/{chunk-F2DIOJJZ.mjs → chunk-XCQQIPCO.mjs} +5 -46
- package/dist/agent-verifier/chunk-XCQQIPCO.mjs.map +1 -0
- package/dist/agent-verifier/{global-config-NYCSCAUI.mjs → global-config-2NUESNEQ.mjs} +5 -5
- package/dist/agent-verifier/{keychain-backend-A3MRWLPF.mjs → keychain-backend-FF4I6ODB.mjs} +11 -6
- package/dist/agent-verifier/keychain-backend-FF4I6ODB.mjs.map +1 -0
- package/dist/agent-verifier/{local-files-QVJ2H3MH.mjs → local-files-OF4QFISU.mjs} +8 -8
- package/dist/agent-verifier/{chunk-UIOLGH4A.mjs → local-typecheck-DHVLM37Z.mjs} +4 -4
- package/dist/agent-verifier/local-typecheck-DHVLM37Z.mjs.map +1 -0
- package/dist/agent-verifier/{materialize-workspace-OZKOQCSQ.mjs → materialize-workspace-JBDL6LF4.mjs} +22 -22
- package/dist/agent-verifier/materialize-workspace-JBDL6LF4.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-Z6OZWUIZ.mjs → reducer-bundle-preflight-GLUJKTWU.mjs} +75 -24
- package/dist/agent-verifier/reducer-bundle-preflight-GLUJKTWU.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-YDIOW2BO.mjs → reducer-contract-preflight-WVQQPW5F.mjs} +7 -6
- package/dist/agent-verifier/reducer-contract-preflight-WVQQPW5F.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-ON62IGWK.mjs → reducer-native-test-harness-XQUPIT5D.mjs} +480 -703
- package/dist/agent-verifier/reducer-native-test-harness-XQUPIT5D.mjs.map +1 -0
- package/dist/agent-verifier/static-scaffold-U5DXE23S.mjs +24 -0
- package/dist/agent-verifier/{workspace-codegen-WPZHMATU.mjs → workspace-codegen-SPPVHURX.mjs} +3 -3
- package/dist/agent-verifier/{workspace-dependencies-B6A2ZX55.mjs → workspace-dependencies-5HEEKZFP.mjs} +5 -3
- package/dist/authoring-compatibility-internal.js +12 -0
- package/dist/chunk-5IYJOVUA.js +3902 -0
- package/dist/chunk-5IYJOVUA.js.map +1 -0
- package/dist/chunk-6NYVJYN4.js +313 -0
- package/dist/chunk-6NYVJYN4.js.map +1 -0
- package/dist/chunk-EQNBQVIW.js +204 -0
- package/dist/chunk-EQNBQVIW.js.map +1 -0
- package/dist/{chunk-M4SCKH5M.js → chunk-USZAPMQ4.js} +2488 -4993
- package/dist/chunk-USZAPMQ4.js.map +1 -0
- package/dist/{global-config-YBFEGJQG.js → global-config-RBMW7IVA.js} +3 -2
- package/dist/index.js +3099 -6188
- package/dist/index.js.map +1 -1
- package/dist/internal.js +35 -9
- package/dist/internal.js.map +1 -1
- package/dist/{keychain-backend-JHTXAKWC.js → keychain-backend-FSNTNTZE.js} +11 -6
- package/dist/keychain-backend-FSNTNTZE.js.map +1 -0
- package/package.json +9 -19
- package/release/authoring-release-set.json +38 -0
- package/skills/dreamboard/SKILL.md +32 -30
- package/skills/dreamboard/references/building-your-first-game.md +16 -16
- package/skills/dreamboard/references/cli.md +54 -54
- package/skills/dreamboard/references/manifest-authoring.md +11 -3
- package/skills/dreamboard/references/quickstart.md +19 -16
- package/skills/dreamboard/references/testing.md +6 -13
- package/dist/agent-verifier/chunk-27EEIZCI.mjs.map +0 -1
- package/dist/agent-verifier/chunk-5NYBTZB4.mjs.map +0 -1
- package/dist/agent-verifier/chunk-776W3UGV.mjs.map +0 -1
- package/dist/agent-verifier/chunk-C3VW3DTA.mjs.map +0 -1
- package/dist/agent-verifier/chunk-F2DIOJJZ.mjs.map +0 -1
- package/dist/agent-verifier/chunk-G42BGGG2.mjs +0 -70
- package/dist/agent-verifier/chunk-G42BGGG2.mjs.map +0 -1
- package/dist/agent-verifier/chunk-H76MT5UR.mjs.map +0 -1
- package/dist/agent-verifier/chunk-IDVQXGAO.mjs +0 -222
- package/dist/agent-verifier/chunk-IDVQXGAO.mjs.map +0 -1
- package/dist/agent-verifier/chunk-JO5AMVZU.mjs +0 -1744
- package/dist/agent-verifier/chunk-JO5AMVZU.mjs.map +0 -1
- package/dist/agent-verifier/chunk-KDBSVLCF.mjs +0 -624
- package/dist/agent-verifier/chunk-KDBSVLCF.mjs.map +0 -1
- package/dist/agent-verifier/chunk-MW2QIWWA.mjs.map +0 -1
- package/dist/agent-verifier/chunk-NAK77WXW.mjs.map +0 -1
- package/dist/agent-verifier/chunk-ON62IGWK.mjs.map +0 -1
- package/dist/agent-verifier/chunk-QZH6IEZS.mjs +0 -39
- package/dist/agent-verifier/chunk-QZH6IEZS.mjs.map +0 -1
- package/dist/agent-verifier/chunk-TAEQKBJB.mjs.map +0 -1
- package/dist/agent-verifier/chunk-UIOLGH4A.mjs.map +0 -1
- package/dist/agent-verifier/chunk-XQXDOBYB.mjs.map +0 -1
- package/dist/agent-verifier/chunk-YDIOW2BO.mjs.map +0 -1
- package/dist/agent-verifier/chunk-Z6OZWUIZ.mjs.map +0 -1
- package/dist/agent-verifier/compile-576O7TYP.mjs +0 -312
- package/dist/agent-verifier/compile-576O7TYP.mjs.map +0 -1
- package/dist/agent-verifier/keychain-backend-A3MRWLPF.mjs.map +0 -1
- package/dist/agent-verifier/local-typecheck-2JWG5IGL.mjs +0 -10
- package/dist/agent-verifier/materialize-workspace-OZKOQCSQ.mjs.map +0 -1
- package/dist/agent-verifier/reducer-bundle-preflight-7NYZF5ZT.mjs +0 -20
- package/dist/agent-verifier/reducer-contract-preflight-COD2CO22.mjs +0 -11
- package/dist/agent-verifier/reducer-native-test-harness-QC7HZUK4.mjs +0 -50
- package/dist/agent-verifier/static-scaffold-JBUE3ROP.mjs +0 -27
- package/dist/agent-verifier/sync-C6S3OGCD.mjs +0 -588
- package/dist/agent-verifier/sync-C6S3OGCD.mjs.map +0 -1
- package/dist/agent-verifier/test-Y5UGQV7J.mjs +0 -353
- package/dist/agent-verifier/test-Y5UGQV7J.mjs.map +0 -1
- package/dist/agent-verifier/workspace-codegen-WPZHMATU.mjs.map +0 -1
- package/dist/agent-verifier/workspace-dependencies-B6A2ZX55.mjs.map +0 -1
- package/dist/chunk-3NRROR4P.js +0 -432
- package/dist/chunk-3NRROR4P.js.map +0 -1
- package/dist/chunk-M4SCKH5M.js.map +0 -1
- package/dist/dev-host/components/drawer.tsx +0 -132
- package/dist/dev-host/components/input.tsx +0 -21
- package/dist/dev-host/dev-api-proxy-plugin.ts +0 -328
- package/dist/dev-host/dev-author-dom-warnings.ts +0 -100
- package/dist/dev-host/dev-diagnostics.ts +0 -62
- package/dist/dev-host/dev-fallback-stylesheet.ts +0 -53
- package/dist/dev-host/dev-hmr-guard-plugin.ts +0 -47
- package/dist/dev-host/dev-host-controller.ts +0 -674
- package/dist/dev-host/dev-host-player-query.ts +0 -17
- package/dist/dev-host/dev-host-session-transport.ts +0 -52
- package/dist/dev-host/dev-host-storage.ts +0 -56
- package/dist/dev-host/dev-log-relay-plugin.ts +0 -510
- package/dist/dev-host/dev-runtime-config.ts +0 -14
- package/dist/dev-host/dev-runtime-platform.ts +0 -335
- package/dist/dev-host/dev-virtual-modules-plugin.ts +0 -64
- package/dist/dev-host/host-main.css +0 -224
- package/dist/dev-host/host-main.tsx +0 -948
- package/dist/dev-host/index.html +0 -56
- package/dist/dev-host/lib/utils.ts +0 -6
- package/dist/dev-host/plugin-main.ts +0 -61
- package/dist/dev-host/plugin.html +0 -24
- package/dist/dev-host/shared-styles.css +0 -144
- package/dist/dev-host/start-dev-server.ts +0 -140
- package/dist/dev-host/virtual-modules.d.ts +0 -27
- package/dist/global-config-YBFEGJQG.js.map +0 -1
- package/dist/keychain-backend-JHTXAKWC.js.map +0 -1
- package/skills/dreamboard/scripts/events-extract.mjs +0 -218
- /package/dist/agent-verifier/{chunk-XKCJBIRY.mjs.map → chunk-QD4SQNUP.mjs.map} +0 -0
- /package/dist/agent-verifier/{global-config-NYCSCAUI.mjs.map → global-config-2NUESNEQ.mjs.map} +0 -0
- /package/dist/agent-verifier/{local-files-QVJ2H3MH.mjs.map → local-files-OF4QFISU.mjs.map} +0 -0
- /package/dist/agent-verifier/{local-typecheck-2JWG5IGL.mjs.map → static-scaffold-U5DXE23S.mjs.map} +0 -0
- /package/dist/agent-verifier/{reducer-bundle-preflight-7NYZF5ZT.mjs.map → workspace-codegen-SPPVHURX.mjs.map} +0 -0
- /package/dist/agent-verifier/{reducer-contract-preflight-COD2CO22.mjs.map → workspace-dependencies-5HEEKZFP.mjs.map} +0 -0
- /package/dist/{agent-verifier/reducer-native-test-harness-QC7HZUK4.mjs.map → authoring-compatibility-internal.js.map} +0 -0
- /package/dist/{agent-verifier/static-scaffold-JBUE3ROP.mjs.map → global-config-RBMW7IVA.js.map} +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/app/tsconfig.framework.json +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/app/tsconfig.json +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/index.tsx +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/style.css +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/tsconfig.framework.json +0 -0
- /package/{dist/scaffold → scaffold}/assets/static/ui/tsconfig.json +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/testing/reducer-native-test-harness.ts","../../src/services/gameplay-authority-submit.ts","../../../../node_modules/.pnpm/@dreamboard-games+gameplay-authority-protocol@0.1.0-alpha.0/node_modules/@dreamboard-games/gameplay-authority-protocol/dist/frames.js","../../../../node_modules/.pnpm/@dreamboard-games+gameplay-authority-client@0.1.0-alpha.1/node_modules/@dreamboard-games/gameplay-authority-client/dist/index.js","../../src/ui/playwright-runner.ts","../../src/services/workflows/resolve-setup-profile.ts","../../src/utils/session-game-source.ts"],"sourcesContent":["import path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport type { Browser, Page } from \"playwright\";\nimport type {\n BoardSpec,\n GameTopologyManifest,\n} from \"@dreamboard-games/sdk/types\";\nimport {\n createProjectSessionFromReducerSnapshot,\n createProjectSession,\n getSessionSnapshot,\n startGame,\n type HostPlayerGameplayView,\n} from \"@dreamboard-games/api-client\";\nimport {\n contractFingerprint,\n createReducerBundle,\n} from \"@dreamboard-games/sdk/reducer\";\nimport {\n ReducerWireZod as ReducerContractZod,\n type ReducerWire as Wire,\n} from \"@dreamboard-games/sdk/reducer-contract\";\nimport { materializeManifestTable } from \"@dreamboard-games/sdk/codegen\";\nimport type { ProjectConfig, ResolvedConfig } from \"../../types.js\";\nimport {\n ensureDir,\n exists,\n readTextFileIfExists,\n writeJsonFile,\n writeTextFile,\n} from \"../../utils/fs.js\";\nimport {\n importTypeScriptModule,\n bundleTypeScriptModuleText,\n} from \"../../utils/ts-module-loader.js\";\nimport { hashContent } from \"../../utils/crypto.js\";\nimport { loadManifest } from \"../project/local-files.js\";\nimport {\n REDUCER_TESTING_TYPES_WRAPPER_CONTENT,\n buildReducerTestingContractContent,\n} from \"../../templates/testing-types-content.js\";\nimport { submitGameplayAuthorityAction } from \"../gameplay-authority-submit.js\";\nimport {\n buildBrowserAuthInitScript,\n configurePlaywrightBrowsersPath,\n waitForGameReady,\n} from \"../../ui/playwright-runner.js\";\nimport { resolveSetupProfileSelection } from \"../workflows/resolve-setup-profile.js\";\nimport {\n isStaleContractArtifactError,\n STALE_CONTRACT_ARTIFACT_CODE,\n toDreamboardApiError,\n} from \"../../utils/errors.js\";\nimport { PROJECT_DIR_NAME } from \"../../constants.js\";\nimport { projectIdFromSessionGameSource } from \"../../utils/session-game-source.js\";\n\n// Opt in to SDK authoring warnings (e.g. concrete dependent-choice defaults).\n// Trusted reducer code cannot read process.env, so the SDK gates authoring\n// warnings on this host-set global instead.\n(globalThis as Record<string, unknown>).__DREAMBOARD_AUTHORING_WARNINGS__ =\n true;\n\nconst GENERATED_TESTING_TYPES_PREFIX = \"// Generated by dreamboard\";\nconst TESTING_TYPES_STUB =\n \"export function defineScenario(scenario) { return scenario; }\\n\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst BASE_SUFFIX = \".base.ts\";\nconst SCENARIO_SUFFIX = \".scenario.ts\";\nconst SDK_UI_RUNTIME_EXTERNALS = [\n \"@radix-ui/react-accordion\",\n \"@radix-ui/react-dialog\",\n \"@radix-ui/react-label\",\n \"@radix-ui/react-select\",\n \"@radix-ui/react-slot\",\n \"@radix-ui/react-tooltip\",\n \"@use-gesture/react\",\n \"clsx\",\n \"framer-motion\",\n \"lucide-react\",\n \"react\",\n \"react-dom\",\n \"vaul\",\n] as const;\n\ntype TestRunnerName = \"reducer\" | \"remote\" | \"browser\";\n\ntype TypedBaseDefinition = {\n id: string;\n seed?: number;\n players?: number;\n setupProfileId?: string;\n extends?: string;\n setup: (ctx: BaseContext) => void | Promise<void>;\n};\n\ntype ResolvedBaseDefinition = TypedBaseDefinition & {\n seed: number;\n players: number;\n};\n\ntype TypedScenarioDefinition = {\n id: string;\n description?: string;\n from: string;\n runners?: readonly TestRunnerName[];\n phase?: string;\n stage?: string;\n when: (ctx: SharedScenarioContext) => void | Promise<void>;\n then: (ctx: SharedScenarioContext) => void | Promise<void>;\n};\n\ntype LoadedBase = {\n filePath: string;\n definition: TypedBaseDefinition;\n bundleHash: string;\n};\n\ntype LoadedScenario = {\n filePath: string;\n definition: TypedScenarioDefinition;\n bundleHash: string;\n};\n\ntype ExpectMatchers = {\n toBe: (expected: unknown) => void;\n toEqual: (expected: unknown) => void;\n toBeDefined: () => void;\n toBeUndefined: () => void;\n toBeNull: () => void;\n toContain: (expected: unknown) => void;\n toBeGreaterThan: (expected: number) => void;\n toBeGreaterThanOrEqual: (expected: number) => void;\n};\n\ntype ExpectApi = (actual: unknown) => ExpectMatchers;\n\ntype HistoryInput = {\n kind: \"interaction\";\n playerId: string;\n interactionId: string;\n params: Record<string, unknown>;\n};\n\ntype HistoryRecord = {\n input: HistoryInput;\n accepted: boolean;\n errorCode?: string;\n message?: string;\n};\n\ntype BaseStateArtifact = {\n key: string;\n base: string;\n snapshot: Record<string, unknown>;\n version: number;\n fingerprint: {\n base: string;\n seed: number;\n players: number;\n baseBundleHash: string;\n manifestHash: string;\n appBundleHash: string;\n uiContractHash: string;\n setupProfileId?: string | null;\n compiledResultId?: string;\n gameId?: string;\n parentBaseId?: string | null;\n parentFingerprintHash?: string | null;\n contractFingerprint?: string;\n };\n};\n\ntype BaseStateFile = Record<string, BaseStateArtifact>;\n\ntype BaseContext = {\n game: ScenarioGameApi;\n players: () => readonly string[];\n seat: (index: number) => string;\n};\n\ntype SharedScenarioContext = BaseContext & {\n state: () => string;\n view: (playerId: string) => unknown;\n interactions: (playerId: string) => readonly Record<string, unknown>[];\n explain: (playerId: string, interactionId: string) => unknown;\n expect: ExpectApi;\n};\n\ntype ScenarioGameApi = {\n start: () => Promise<void>;\n patchState: (\n mutator: (state: Record<string, unknown>) => void,\n ) => Promise<void>;\n submit: (\n playerId: string,\n interactionId: string,\n params?: Record<string, unknown>,\n ) => Promise<void>;\n};\n\ntype SubmissionError = Error & { errorCode?: string };\n\ntype BrowserDriverModule = {\n default?: BrowserRunnerDriver;\n} & Partial<BrowserRunnerDriver>;\n\ntype BrowserRunnerDriver = {\n onReady?: (bridge: BrowserBridgeClient) => Promise<void> | void;\n interaction?: (\n bridge: BrowserBridgeClient,\n input: {\n playerId: string;\n interactionId: string;\n params: unknown;\n },\n ) => Promise<boolean | void> | boolean | void;\n};\n\ntype BrowserSnapshot = {\n sessionId: string | null;\n shortCode: string | null;\n version: number;\n currentPhase: string | null;\n controllingPlayerId: string;\n controllablePlayerIds: string[];\n view: unknown;\n availableInteractions?: string[];\n};\n\nexport type ReducerNativeScenarioResult = {\n id: string;\n success: boolean;\n error?: string;\n errorCode?: string;\n};\n\nexport type ReducerNativeScenarioSummary = {\n passed: number;\n failed: number;\n results: ReducerNativeScenarioResult[];\n};\n\nexport function formatScenarioErrorForDisplay(options: {\n error: Error;\n projectRoot: string;\n scenarioFilePath: string;\n}): string {\n const message = options.error.message || \"Scenario failed.\";\n const scenarioFrame = findScenarioStackFrame({\n stack: options.error.stack,\n projectRoot: options.projectRoot,\n scenarioFilePath: options.scenarioFilePath,\n });\n return scenarioFrame ? `${message}\\n${scenarioFrame}` : message;\n}\n\nfunction findScenarioStackFrame(options: {\n stack: string | undefined;\n projectRoot: string;\n scenarioFilePath: string;\n}): string | null {\n if (!options.stack) {\n return null;\n }\n\n const absolutePath = path.resolve(options.scenarioFilePath);\n const relativePath = path.relative(options.projectRoot, absolutePath);\n const normalizedRelativePath = relativePath.split(path.sep).join(\"/\");\n const escapedAbsolutePath = escapeRegExp(absolutePath);\n const escapedRelativePath = escapeRegExp(normalizedRelativePath);\n const absoluteFrame = new RegExp(`${escapedAbsolutePath}:(\\\\d+):(\\\\d+)`);\n const relativeFrame = new RegExp(`${escapedRelativePath}:(\\\\d+):(\\\\d+)`);\n\n for (const line of options.stack.split(\"\\n\")) {\n const normalizedLine = line.split(path.sep).join(\"/\");\n const match =\n normalizedLine.match(absoluteFrame) ??\n normalizedLine.match(relativeFrame);\n if (match?.[1] && match?.[2]) {\n return `at ${normalizedRelativePath}:${match[1]}:${match[2]}`;\n }\n }\n\n return null;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport type SeededScenarioSession = {\n sessionId: string;\n shortCode: string;\n gameId: string;\n seed: number;\n playerCount: number;\n setupProfileId: string | null;\n scenarioId: string;\n phase: string | null;\n stage: string | null;\n materialization?: {\n mode: \"snapshot\";\n totalMs: number;\n reducerHarnessMs: number;\n backendHydrateMs: number;\n };\n};\n\nexport type MaterializedScenarioReducerState = {\n baseId: string;\n scenarioId: string;\n seed: number;\n playerCount: number;\n setupProfileId: string | null;\n reducerState: Record<string, unknown>;\n reducerStateVersion: number;\n fingerprintMetadata: Record<string, string>;\n phase: string | null;\n stage: string | null;\n};\n\nexport type LiveReplayActionDiagnostic = {\n index: number;\n playerId: string;\n interactionId: string;\n inputs?: JsonObject;\n expectedVersion: number;\n actionSetVersion: string;\n responseStatus?: number;\n responseBody?: string;\n accepted?: boolean;\n errorCode?: string;\n backendTiming?: string;\n durationMs: number;\n};\n\nexport type LiveReplayScenarioResult = SeededScenarioSession & {\n diagnostics: LiveReplayActionDiagnostic[];\n};\n\nexport type LiveReplayActionPlanSession = SeededScenarioSession;\n\nexport type LiveReplayActionPlan = {\n gameId: string;\n seed: number;\n playerCount: number;\n setupProfileId: string | null;\n scenarioId: string;\n phase: string | null;\n stage: string | null;\n diagnostics: LiveReplayActionDiagnostic[];\n};\n\ntype JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\ntype JsonObject = { [key: string]: JsonValue };\n\ntype BrowserBridgeClient = {\n snapshot: () => Promise<BrowserSnapshot>;\n submitInteraction: (\n playerId: string,\n interactionId: string,\n params: unknown,\n ) => Promise<void>;\n waitForVersionChange: (\n previousVersion: number,\n timeoutMs?: number,\n ) => Promise<BrowserSnapshot>;\n};\n\ntype GameplaySnapshot = {\n version: number;\n actionSetVersion: string;\n currentPhase: string | null;\n playerId: string;\n view: unknown;\n availableInteractions: string[];\n};\n\nlet testingExpectApiFactoryPromise:\n | Promise<\n (options?: {\n matchSnapshot?: (name: string | undefined, actual: unknown) => void;\n }) => ExpectApi\n >\n | undefined;\n\nasync function loadTestingExpectApiFactory(): Promise<\n (options?: {\n matchSnapshot?: (name: string | undefined, actual: unknown) => void;\n }) => ExpectApi\n> {\n testingExpectApiFactoryPromise ??=\n import(\"@dreamboard-games/sdk/testing\").then(\n (module) =>\n module.createExpectApi as (options?: {\n matchSnapshot?: (name: string | undefined, actual: unknown) => void;\n }) => ExpectApi,\n );\n return testingExpectApiFactoryPromise;\n}\n\nfunction createSubmissionError(\n errorCode: string | undefined,\n message: string | undefined,\n fallbackMessage: string,\n): SubmissionError {\n const error = new Error(message ?? fallbackMessage) as SubmissionError;\n error.name = \"SubmissionError\";\n error.errorCode = errorCode;\n return error;\n}\n\nfunction parseJsonValue(value: unknown): unknown {\n if (typeof value !== \"string\") {\n return value;\n }\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nfunction deepEqual(left: unknown, right: unknown): boolean {\n return isDeepStrictEqual(left, right);\n}\n\nfunction normalizeScenarioRunners(\n runners: readonly TestRunnerName[] | undefined,\n): readonly TestRunnerName[] {\n return runners && runners.length > 0 ? runners : [\"reducer\"];\n}\n\nfunction shouldRefreshReducerTestingTypes(\n existingContent: string | null,\n): boolean {\n if (\n existingContent === null ||\n existingContent.trim().length === 0 ||\n existingContent === TESTING_TYPES_STUB ||\n existingContent.startsWith(GENERATED_TESTING_TYPES_PREFIX)\n ) {\n return true;\n }\n return false;\n}\n\nasync function discoverFiles(root: string, suffix: string): Promise<string[]> {\n if (!(await exists(root))) {\n return [];\n }\n const entries = await readdir(root, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const entryPath = path.join(root, entry.name);\n if (entry.isDirectory()) {\n files.push(...(await discoverFiles(entryPath, suffix)));\n continue;\n }\n if (entry.isFile() && entry.name.endsWith(suffix)) {\n files.push(entryPath);\n }\n }\n files.sort();\n return files;\n}\n\nfunction isFunction(value: unknown): value is (...args: never[]) => unknown {\n return typeof value === \"function\";\n}\n\nfunction parseTypedBaseDefinition(value: unknown): TypedBaseDefinition {\n if (\n typeof value !== \"object\" ||\n value === null ||\n !(\"id\" in value) ||\n typeof value.id !== \"string\" ||\n !(\"setup\" in value) ||\n !isFunction(value.setup)\n ) {\n throw new Error(\"Invalid reducer-native base definition.\");\n }\n const parentBaseId =\n \"extends\" in value && typeof value.extends === \"string\"\n ? value.extends\n : undefined;\n const seed =\n \"seed\" in value && typeof value.seed === \"number\" ? value.seed : undefined;\n const players =\n \"players\" in value && typeof value.players === \"number\"\n ? value.players\n : undefined;\n if ((seed === undefined || players === undefined) && !parentBaseId) {\n throw new Error(\n \"Invalid reducer-native base definition. Base definitions without --extends must declare numeric seed and players.\",\n );\n }\n const setupProfileId =\n \"setupProfileId\" in value && typeof value.setupProfileId === \"string\"\n ? value.setupProfileId\n : undefined;\n return {\n ...(value as TypedBaseDefinition),\n seed,\n players,\n setupProfileId,\n extends: parentBaseId,\n };\n}\n\nfunction parseTypedScenarioDefinition(value: unknown): TypedScenarioDefinition {\n if (\n typeof value !== \"object\" ||\n value === null ||\n !(\"id\" in value) ||\n typeof value.id !== \"string\" ||\n !(\"from\" in value) ||\n typeof value.from !== \"string\" ||\n !(\"when\" in value) ||\n !isFunction(value.when) ||\n !(\"then\" in value) ||\n !isFunction(value.then)\n ) {\n throw new Error(\"Invalid reducer-native scenario definition.\");\n }\n const phase =\n \"phase\" in value && typeof value.phase === \"string\"\n ? value.phase\n : undefined;\n const stage =\n \"stage\" in value && typeof value.stage === \"string\"\n ? value.stage\n : undefined;\n return {\n ...(value as TypedScenarioDefinition),\n phase,\n stage,\n };\n}\n\nexport async function isReducerNativeTestingWorkspace(\n projectRoot: string,\n): Promise<boolean> {\n return (\n (await exists(path.join(projectRoot, \"app\", \"game.ts\"))) &&\n (await exists(\n path.join(projectRoot, \"shared\", \"generated\", \"ui-contract.ts\"),\n ))\n );\n}\n\nexport async function ensureReducerNativeTestingFiles(\n projectRoot: string,\n): Promise<void> {\n const testingTypesPath = path.join(projectRoot, \"test\", \"testing-types.ts\");\n const testingContractPath = path.join(\n projectRoot,\n \"test\",\n \"generated\",\n \"testing-contract.ts\",\n );\n const baseStatesPath = path.join(\n projectRoot,\n \"test\",\n \"generated\",\n \"base-states.generated.ts\",\n );\n const baseStatesDtsPath = path.join(\n projectRoot,\n \"test\",\n \"generated\",\n \"base-states.generated.d.ts\",\n );\n const scenarioManifestPath = path.join(\n projectRoot,\n \"test\",\n \"generated\",\n \"scenario-manifest.generated.ts\",\n );\n\n await ensureDir(path.dirname(testingTypesPath));\n await ensureDir(path.dirname(testingContractPath));\n\n const existingTestingTypes = await readTextFileIfExists(testingTypesPath);\n if (shouldRefreshReducerTestingTypes(existingTestingTypes)) {\n await writeTextFile(\n testingTypesPath,\n REDUCER_TESTING_TYPES_WRAPPER_CONTENT,\n );\n }\n\n const rejectionCodes = await collectKnownRejectionCodes(projectRoot);\n await writeTextFile(\n testingContractPath,\n buildReducerTestingContractContent({ rejectionCodes }),\n );\n\n const header =\n \"// Generated by dreamboard test generate. Do not edit by hand.\\n\";\n if (!(await exists(baseStatesPath))) {\n await writeTextFile(\n baseStatesPath,\n `${header}export const BASE_STATES = {} as const;\\nexport const BASE_STATES_CONTRACT_FINGERPRINT = undefined;\\n`,\n );\n } else {\n const existingBaseStates = await readTextFileIfExists(baseStatesPath);\n if (\n existingBaseStates &&\n !existingBaseStates.includes(\"BASE_STATES_CONTRACT_FINGERPRINT\")\n ) {\n await writeTextFile(\n baseStatesPath,\n `${existingBaseStates.trimEnd()}\\nexport const BASE_STATES_CONTRACT_FINGERPRINT = undefined;\\n`,\n );\n }\n }\n if (!(await exists(baseStatesDtsPath))) {\n await writeTextFile(\n baseStatesDtsPath,\n `${header}export declare const BASE_STATES: Record<string, unknown>;\\nexport declare const BASE_STATES_CONTRACT_FINGERPRINT: string | undefined;\\n`,\n );\n } else {\n const existingBaseStatesDts = await readTextFileIfExists(baseStatesDtsPath);\n if (\n existingBaseStatesDts &&\n !existingBaseStatesDts.includes(\"BASE_STATES_CONTRACT_FINGERPRINT\")\n ) {\n await writeTextFile(\n baseStatesDtsPath,\n `${existingBaseStatesDts.trimEnd()}\\nexport declare const BASE_STATES_CONTRACT_FINGERPRINT: string | undefined;\\n`,\n );\n }\n }\n if (!(await exists(scenarioManifestPath))) {\n await writeTextFile(\n scenarioManifestPath,\n `${header}export const SCENARIO_MANIFEST = [] as const;\\n`,\n );\n }\n}\n\nconst DEFAULT_REJECTION_CODES = [\n \"NOT_YOUR_TURN\",\n \"action-unavailable\",\n \"invalid-action-params\",\n \"prompt-not-owned\",\n] as const;\n\nasync function collectKnownRejectionCodes(\n projectRoot: string,\n): Promise<string[]> {\n const knownCodes = new Set<string>(DEFAULT_REJECTION_CODES);\n const gamePath = path.join(projectRoot, \"app\", \"game.ts\");\n if (!(await exists(gamePath))) {\n return Array.from(knownCodes).sort((left, right) =>\n left.localeCompare(right),\n );\n }\n\n try {\n const module =\n await importTypeScriptModule<Record<string, unknown>>(gamePath);\n const phases =\n (\n module.default as {\n phases?: Record<\n string,\n {\n interactions?: Record<string, { errorCodes?: readonly string[] }>;\n }\n >;\n }\n )?.phases ?? {};\n for (const phase of Object.values(phases)) {\n const interactions = phase.interactions ?? {};\n for (const interaction of Object.values(interactions)) {\n for (const errorCode of interaction.errorCodes ?? []) {\n if (typeof errorCode === \"string\" && errorCode.length > 0) {\n knownCodes.add(errorCode);\n }\n }\n }\n }\n } catch {\n // Keep the generated contract usable even if the game module fails to load.\n }\n\n return Array.from(knownCodes).sort((left, right) =>\n left.localeCompare(right),\n );\n}\n\nexport async function loadTypedBases(\n projectRoot: string,\n): Promise<LoadedBase[]> {\n const baseFiles = await discoverFiles(\n path.join(projectRoot, \"test\", \"bases\"),\n BASE_SUFFIX,\n );\n const loaded: LoadedBase[] = [];\n for (const filePath of baseFiles) {\n const externals = reducerNativeTestHelperExternals(projectRoot, filePath);\n const [module, bundledText] = await Promise.all([\n importTypeScriptModule<Record<string, unknown>>(filePath),\n bundleTypeScriptModuleText(filePath, { external: externals }),\n ]);\n loaded.push({\n filePath,\n definition: parseTypedBaseDefinition(module.default),\n bundleHash: hashContent(bundledText),\n });\n }\n return loaded;\n}\n\nexport async function loadTypedScenarios(\n projectRoot: string,\n options: { scenarioPath?: string },\n): Promise<LoadedScenario[]> {\n const scenarioFiles = options.scenarioPath\n ? [path.resolve(projectRoot, options.scenarioPath)]\n : await discoverFiles(\n path.join(projectRoot, \"test\", \"scenarios\"),\n SCENARIO_SUFFIX,\n );\n const loaded: LoadedScenario[] = [];\n for (const filePath of scenarioFiles) {\n const externals = reducerNativeTestHelperExternals(projectRoot, filePath);\n const [module, bundledText] = await Promise.all([\n importTypeScriptModule<Record<string, unknown>>(filePath),\n bundleTypeScriptModuleText(filePath, { external: externals }),\n ]);\n loaded.push({\n filePath,\n definition: parseTypedScenarioDefinition(module.default),\n bundleHash: hashContent(bundledText),\n });\n }\n return loaded;\n}\n\nfunction reducerNativeTestHelperExternals(\n projectRoot: string,\n filePath: string,\n): string[] {\n const testingTypesPath = path.join(projectRoot, \"test\", \"testing-types\");\n const relative = path\n .relative(path.dirname(filePath), testingTypesPath)\n .replaceAll(\"\\\\\", \"/\");\n const specifier = relative.startsWith(\".\") ? relative : `./${relative}`;\n return [specifier, `${specifier}.ts`, ...SDK_UI_RUNTIME_EXTERNALS];\n}\n\nconst JS_MAX_SAFE_INTEGER = 9_007_199_254_740_991n;\nconst JS_MIN_SAFE_INTEGER = -JS_MAX_SAFE_INTEGER;\nconst JS_MAX_SAFE_INTEGER_EXCLUSIVE = JS_MAX_SAFE_INTEGER + 1n;\n\nclass KotlinSeededRandom {\n private x: number;\n private y: number;\n private z: number;\n private w: number;\n private v: number;\n private addend: number;\n\n constructor(seed: number) {\n const seedBig = BigInt.asIntN(64, BigInt(Math.trunc(seed)));\n const seed1 = Number(BigInt.asIntN(32, seedBig));\n const seed2 = Number(BigInt.asIntN(32, seedBig >> 32n));\n\n this.x = seed1 | 0;\n this.y = seed2 | 0;\n this.z = 0;\n this.w = 0;\n this.v = ~seed1;\n this.addend = ((seed1 << 10) ^ (seed2 >>> 4)) | 0;\n\n if ((this.x | this.y | this.z | this.w | this.v) === 0) {\n throw new Error(\n \"Kotlin random seed must initialize at least one state word.\",\n );\n }\n\n for (let index = 0; index < 64; index += 1) {\n this.nextInt();\n }\n }\n\n nextInt(): number {\n let next = this.x | 0;\n next ^= next >>> 2;\n this.x = this.y;\n this.y = this.z;\n this.z = this.w;\n const currentV = this.v | 0;\n this.w = currentV;\n next = (next ^ (next << 1) ^ currentV ^ (currentV << 4)) | 0;\n this.v = next;\n this.addend = (this.addend + 362437) | 0;\n return (next + this.addend) | 0;\n }\n\n private nextBits(bitCount: number): number {\n if (bitCount <= 0) {\n return 0;\n }\n return this.nextInt() >>> (32 - bitCount);\n }\n\n nextIntBound(bound: number): number {\n if (bound <= 0) {\n throw new Error(\"bound must be positive\");\n }\n\n if ((bound & -bound) === bound) {\n const bitCount = 31 - Math.clz32(bound);\n return this.nextBits(bitCount);\n }\n\n let value: number;\n while (true) {\n const bits = this.nextInt() >>> 1;\n value = bits % bound;\n if (bits - value + (bound - 1) >= 0) {\n return value;\n }\n }\n }\n\n nextLong(): number {\n return Number(this.nextLongBigInt());\n }\n\n private nextLongBigInt(): bigint {\n const high = BigInt(this.nextInt());\n const low = BigInt(this.nextInt());\n return BigInt.asIntN(64, (high << 32n) + low);\n }\n\n nextReducerRuntimeSeed(): number {\n return Number(\n this.nextLongRange(JS_MIN_SAFE_INTEGER, JS_MAX_SAFE_INTEGER_EXCLUSIVE),\n );\n }\n\n private nextLongRange(from: bigint, until: bigint): bigint {\n if (until <= from) {\n throw new Error(\"until must be greater than from\");\n }\n\n const bound = until - from;\n const mask = bound - 1n;\n if ((bound & mask) === 0n) {\n return from + (BigInt.asUintN(64, this.nextLongBigInt()) & mask);\n }\n\n while (true) {\n const bits = BigInt.asUintN(64, this.nextLongBigInt()) >> 1n;\n const value = bits % bound;\n if (BigInt.asIntN(64, bits + mask - value) >= 0n) {\n return from + value;\n }\n }\n }\n}\n\nfunction shuffleWithKotlinRandom<T>(\n values: readonly T[],\n random: KotlinSeededRandom,\n): T[] {\n const next = [...values];\n for (let index = next.length - 1; index > 0; index -= 1) {\n const swapIndex = random.nextIntBound(index + 1);\n const current = next[index];\n next[index] = next[swapIndex] as T;\n next[swapIndex] = current as T;\n }\n return next;\n}\n\ntype EffectiveBaseSetup = {\n setupProfileId: string | null;\n};\n\ntype GeneratedInitialTableFactory = (options?: {\n playerIds?: readonly string[];\n shuffleItems?: <Value>(values: readonly Value[]) => Value[];\n}) => Record<string, unknown>;\n\nfunction resolveEffectiveBaseSetup(options: {\n manifest: GameTopologyManifest;\n base: TypedBaseDefinition;\n basesById?: Map<string, LoadedBase>;\n}): EffectiveBaseSetup {\n const inheritedSetupProfileId =\n options.base.setupProfileId ??\n (options.base.extends && options.basesById\n ? resolveEffectiveBaseSetup({\n manifest: options.manifest,\n base:\n options.basesById.get(options.base.extends)?.definition ??\n (() => {\n throw new Error(\n `Base '${options.base.id}' extends unknown parent '${options.base.extends}'.`,\n );\n })(),\n basesById: options.basesById,\n }).setupProfileId\n : undefined);\n const selection = resolveSetupProfileSelection({\n manifest: options.manifest,\n requestedSetupProfileId: inheritedSetupProfileId ?? undefined,\n });\n return {\n setupProfileId: selection.id,\n };\n}\n\nfunction resolveBaseDefinition(\n base: LoadedBase,\n basesById: Map<string, LoadedBase>,\n): ResolvedBaseDefinition {\n const inherited =\n base.definition.extends !== undefined\n ? resolveBaseDefinition(\n basesById.get(base.definition.extends) ??\n (() => {\n throw new Error(\n `Base '${base.definition.id}' extends unknown parent '${base.definition.extends}'.`,\n );\n })(),\n basesById,\n )\n : null;\n\n const seed = base.definition.seed ?? inherited?.seed;\n const players = base.definition.players ?? inherited?.players;\n if (seed === undefined || players === undefined) {\n throw new Error(\n `Base '${base.definition.id}' must resolve numeric seed and players.`,\n );\n }\n\n return {\n ...base.definition,\n seed,\n players,\n setupProfileId:\n base.definition.setupProfileId ?? inherited?.setupProfileId ?? undefined,\n };\n}\n\nfunction summarizeTableValidationError(\n manifest: GameTopologyManifest,\n error: Error,\n): string {\n const issues = error.message\n .split(\"; \")\n .map((issue) => issue.trim())\n .filter((issue) => issue.length > 0);\n\n if (\n issues.length === 0 ||\n !issues.every((issue) => issue.startsWith(\"table\"))\n ) {\n return error.message;\n }\n\n const boardBaseIdByRuntimeId = new Map<string, string>(\n (manifest.boards ?? []).flatMap((board: BoardSpec) =>\n board.scope === \"perPlayer\"\n ? Array.from(\n { length: manifest.players.maxPlayers },\n (_, index) =>\n [`${board.id}:player-${index + 1}`, board.id] as const,\n )\n : ([[board.id, board.id]] as const),\n ),\n );\n\n const representativeIssues = issues.slice(0, 3).map((issue) => {\n const [, runtimeBoardId = \"\"] =\n issue.match(/^table\\.boards\\.byId\\.([^.]+)\\./) ?? [];\n const boardBaseId = boardBaseIdByRuntimeId.get(runtimeBoardId);\n if (!boardBaseId) {\n return `- ${issue.replace(/^table\\./, \"\")}`;\n }\n const boardSpecificPath = issue\n .replace(/^table\\.boards\\.byId\\.[^.]+\\./, \"\")\n .replace(/^table\\./, \"\");\n return `- board '${boardBaseId}' (${runtimeBoardId}): ${boardSpecificPath}`;\n });\n\n return [\n `Reducer-native table validation failed with ${issues.length} issue${issues.length === 1 ? \"\" : \"s\"}.`,\n \"Likely root cause: the generated test table shape does not match the authored manifest topology.\",\n ...representativeIssues,\n \"Pass --debug for the full validation dump.\",\n ].join(\"\\n\");\n}\n\nclass ShadowReducerRuntime {\n private readonly bundle: ReturnType<typeof createReducerBundle>;\n private readonly runtime: ReturnType<\n ReturnType<typeof createReducerBundle>[\"createInProcessRuntime\"]\n >;\n private readonly playerIds: string[];\n private readonly historyRecords: HistoryRecord[] = [];\n private version = 0;\n private started = false;\n\n constructor(\n private readonly manifest: GameTopologyManifest,\n private readonly gameModuleDefault: unknown,\n private readonly createInitialTable: GeneratedInitialTableFactory | null,\n private readonly seed: number,\n private readonly players: number,\n private readonly setupProfileId: string | null,\n private readonly debug = false,\n ) {\n if (\n typeof gameModuleDefault !== \"object\" ||\n gameModuleDefault === null ||\n !(\"contract\" in gameModuleDefault)\n ) {\n throw new Error(\n \"app/game.ts must export a reducer-native game definition.\",\n );\n }\n this.bundle = createReducerBundle(gameModuleDefault as never);\n this.runtime = this.bundle.createInProcessRuntime();\n this.playerIds = Array.from(\n { length: players },\n (_, index) => `player-${index + 1}`,\n );\n }\n\n async start(): Promise<void> {\n if (this.started) {\n return;\n }\n const random = new KotlinSeededRandom(this.seed);\n const shuffleItems = <Value>(values: readonly Value[]) =>\n shuffleWithKotlinRandom(values, random);\n // JSON-roundtrip the materialized table to mirror the backend wire\n // boundary: real flows serialize the table over HTTP, which drops\n // explicit `undefined` property values (e.g. optional card text) that\n // the bundle's strict JSON state schema would otherwise reject.\n const table: unknown = JSON.parse(\n JSON.stringify(\n this.createInitialTable?.({\n playerIds: this.playerIds,\n shuffleItems,\n }) ??\n materializeManifestTable({\n manifest: this.manifest,\n playerIds: this.playerIds,\n shuffleItems,\n }),\n ),\n );\n const rngSeed = random.nextReducerRuntimeSeed();\n try {\n await this.runtime.initialize({\n table: table as never,\n playerIds: this.playerIds,\n rngSeed,\n setup: this.setupProfileId\n ? {\n profileId: this.setupProfileId,\n }\n : null,\n });\n } catch (error) {\n if (!this.debug && error instanceof Error) {\n throw new Error(summarizeTableValidationError(this.manifest, error));\n }\n throw error;\n }\n this.version = 0;\n this.started = true;\n }\n\n phase(): string {\n return (\n ((\n (\n (this.runtime.unsafeState() as { domain?: unknown } | null)\n ?.domain as { flow?: { currentPhase?: string } } | undefined\n )?.flow as { currentPhase?: string } | undefined\n )?.currentPhase ??\n null) ||\n \"\"\n );\n }\n\n playerOrder(): string[] {\n return this.playerIds;\n }\n\n rawState(): Record<string, unknown> {\n return this.runtime.snapshot() as Record<string, unknown>;\n }\n\n currentVersion(): number {\n return this.version;\n }\n\n hydrate(snapshot: Record<string, unknown>, version = 0): void {\n this.runtime.hydrate({ state: structuredClone(snapshot) });\n this.version = version;\n this.started = true;\n }\n\n patchState(mutator: (state: Record<string, unknown>) => void): void {\n const next = structuredClone(this.rawState());\n mutator(next);\n this.hydrate(next, this.version + 1);\n }\n\n projectAllSeats(): {\n currentStage: string | null;\n stageSeats: string[];\n seats: Record<\n string,\n {\n view?: unknown;\n availableInteractions?: Array<Record<string, unknown>>;\n zones?: Record<string, unknown>;\n }\n >;\n } {\n type RawSeatProjection = {\n view?: unknown;\n availableInteractions?: Array<Record<string, unknown>>;\n availableInteractionRefs?: unknown;\n zones?: Record<string, unknown>;\n };\n type RawSeatProjectionBundle = {\n currentStage?: string | null;\n stageSeats?: string[];\n interactionsByRef?: unknown;\n seats?: Record<string, RawSeatProjection>;\n };\n\n const projection = this.runtime.projectSeatsDynamic({\n playerIds: this.playerIds as never,\n }) as RawSeatProjectionBundle;\n const interactionsByRef =\n projection.interactionsByRef &&\n typeof projection.interactionsByRef === \"object\" &&\n !Array.isArray(projection.interactionsByRef)\n ? (projection.interactionsByRef as Record<\n string,\n Record<string, unknown> | undefined\n >)\n : {};\n const seats = Object.fromEntries(\n Object.entries(projection.seats ?? {}).map(([playerId, seat]) => {\n const availableInteractionRefs = Array.isArray(\n seat.availableInteractionRefs,\n )\n ? seat.availableInteractionRefs.filter(\n (ref): ref is string => typeof ref === \"string\",\n )\n : [];\n const availableInteractions =\n seat.availableInteractions ??\n availableInteractionRefs\n .map((ref) => interactionsByRef[ref])\n .filter(\n (descriptor): descriptor is Record<string, unknown> =>\n !!descriptor && typeof descriptor === \"object\",\n );\n return [\n playerId,\n {\n view: seat.view,\n availableInteractions,\n zones: seat.zones,\n },\n ];\n }),\n );\n return {\n currentStage: projection.currentStage ?? null,\n stageSeats: projection.stageSeats ?? [],\n seats,\n };\n }\n\n currentStage(): string | null {\n return this.projectAllSeats().currentStage;\n }\n\n view(playerId: string): unknown {\n return (\n this.runtime.projectSeatViewDynamic({\n playerId: playerId as never,\n }) ?? null\n );\n }\n\n availableInteractionsForPlayer(playerId: string): string[] {\n const projection = this.projectAllSeats();\n const seat = projection.seats[playerId];\n const descriptors = seat?.availableInteractions ?? [];\n return descriptors\n .filter(\n (descriptor) =>\n !!descriptor && typeof descriptor.interactionId === \"string\",\n )\n .map((descriptor) => descriptor.interactionId as string);\n }\n\n /**\n * Phase-kind interaction descriptors (action + prompt) available to\n * `playerId` in the current phase. Surfaces the same projection the UI\n * SDK consumes, so scenarios can assert addressee authorization and\n * availability without reaching into game-specific state. Returned as\n * loose records — the typed `InteractionDescriptor` shape is narrowed\n * downstream in the workspace-generated `testing-contract.ts`.\n */\n interactionsForPlayer(playerId: string): Array<Record<string, unknown>> {\n return this.projectAllSeats().seats[playerId]?.availableInteractions ?? [];\n }\n\n explain(playerId: string, interactionId: string): unknown {\n const runtime = this.runtime as {\n explainInteraction?: (input: {\n playerId: string;\n interactionId: string;\n }) => unknown;\n };\n if (typeof runtime.explainInteraction !== \"function\") {\n throw new Error(\n \"The installed @dreamboard-games/sdk does not expose interaction explanations. Update the workspace SDK pin.\",\n );\n }\n return runtime.explainInteraction({ playerId, interactionId });\n }\n\n clearHistory(): void {\n this.historyRecords.length = 0;\n }\n\n private async applyInput(input: HistoryInput): Promise<void> {\n const parsedInput = toReducerInput(input);\n const result = await this.runtime.dispatch({ input: parsedInput });\n\n if (result.kind === \"reject\") {\n const record = {\n input,\n accepted: false,\n errorCode: result.errorCode,\n message: result.message,\n };\n this.historyRecords.push(record);\n throw createSubmissionError(\n result.errorCode,\n result.message,\n \"Reducer input rejected.\",\n );\n }\n\n this.version += 1;\n this.historyRecords.push({ input, accepted: true });\n }\n\n async submitInteraction(\n playerId: string,\n interactionId: string,\n params: Record<string, unknown>,\n ): Promise<void> {\n await this.applyInput({\n kind: \"interaction\",\n playerId,\n interactionId,\n params,\n });\n }\n}\n\n/**\n * Translate the harness's history record into the unified `interaction`\n * wire shape the ingress bundle accepts.\n */\nfunction toReducerInput(input: HistoryInput): Record<string, unknown> {\n return {\n kind: \"interaction\",\n playerId: input.playerId,\n interactionId: input.interactionId,\n params: input.params,\n };\n}\n\n/**\n * Tracks live gameplay state for the remote runner. Gameplay event streams\n * live in the Gameplay Authority service, so the backend bootstrap snapshot\n * is fetched over REST; post-submit state follows the reducer shadow.\n */\nclass RemoteGameplayTracker {\n private readonly state: GameplaySnapshot = {\n version: -1,\n actionSetVersion: \"\",\n currentPhase: null,\n playerId: \"player-1\",\n view: null,\n availableInteractions: [],\n };\n private liveBootstrap = false;\n\n constructor(\n private readonly sessionId: string,\n private readonly playerId: string,\n ) {\n this.state.playerId = playerId;\n }\n\n async bootstrap(): Promise<void> {\n const { data, error, response } = await getSessionSnapshot({\n path: { sessionId: this.sessionId },\n query: { playerId: this.playerId },\n });\n if (error || !data || data.type !== \"gameplay\") {\n throw toDreamboardApiError(\n error ?? { detail: \"Gameplay snapshot was unavailable.\" },\n response,\n \"Failed to load the remote gameplay bootstrap snapshot\",\n );\n }\n // \"authority\" is the backend sentinel for gameplay state owned by the\n // Gameplay Authority service. The snapshot still attests the session\n // reached gameplay against the real compiled result, but concrete state\n // assertions must follow the reducer shadow instead.\n if (data.gameplay.actionSetVersion === \"authority\") {\n return;\n }\n this.liveBootstrap = true;\n this.applyGameplay(data.gameplay);\n }\n\n hasLiveBootstrap(): boolean {\n return this.liveBootstrap;\n }\n\n snapshot(): GameplaySnapshot {\n return {\n ...this.state,\n availableInteractions: [...this.state.availableInteractions],\n };\n }\n\n applyShadow(shadow: ShadowReducerRuntime): void {\n const projection = shadow.projectAllSeats();\n const playerId = this.playerId;\n const seat = projection.seats[playerId];\n this.state.version = shadow.currentVersion();\n this.state.actionSetVersion = \"\";\n this.state.playerId = playerId;\n this.state.currentPhase = shadow.phase();\n this.state.view = seat?.view ?? null;\n this.state.availableInteractions =\n shadow.availableInteractionsForPlayer(playerId);\n }\n\n private applyGameplay(gameplay: HostPlayerGameplayView): void {\n const playerId = gameplay.perspectivePlayerId;\n const seat = gameplay.seats[playerId];\n this.state.version = gameplay.version;\n this.state.actionSetVersion = gameplay.actionSetVersion;\n this.state.playerId = playerId;\n this.state.currentPhase = gameplay.shared.currentPhase;\n this.state.view = parseSeatView(seat?.view ?? \"null\");\n this.state.availableInteractions = (seat?.availableInteractionRefs ?? [])\n .map((ref) => gameplay.interactionsByRef[ref])\n .filter((interaction): interaction is NonNullable<typeof interaction> =>\n Boolean(interaction),\n )\n .map((interaction) => interaction.interactionId);\n }\n}\n\nfunction parseSeatView(raw: string | null | undefined): unknown {\n return raw ? parseJsonValue(raw) : null;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction formatIssuePath(\n label: string,\n path: ReadonlyArray<PropertyKey>,\n): string {\n let formatted = label;\n for (const segment of path) {\n formatted +=\n typeof segment === \"number\" ? `[${segment}]` : `.${String(segment)}`;\n }\n return formatted;\n}\n\nfunction parseWirePayload<T>(\n methodName: string,\n value: unknown,\n label: string,\n schema: {\n safeParse: (input: unknown) =>\n | { success: true; data: unknown }\n | {\n success: false;\n error: {\n issues: Array<{\n path: Array<PropertyKey>;\n message: string;\n }>;\n };\n };\n },\n): T {\n const parsed = schema.safeParse(value);\n if (parsed.success) {\n return parsed.data as T;\n }\n const firstIssue = parsed.error.issues[0];\n const formattedPath = formatIssuePath(label, firstIssue?.path ?? []);\n throw new Error(\n `Reducer bundle returned invalid payload for '${methodName}': ${formattedPath} ${firstIssue?.message ?? \"failed schema validation\"}.`,\n );\n}\n\nexport function assertDispatchResultWireContract(\n result: unknown,\n): Wire.DispatchResult {\n return parseWirePayload(\n \"dispatch\",\n result,\n \"DispatchResult\",\n ReducerContractZod.DispatchResultSchema,\n );\n}\n\nasync function createBrowserBridgeClient(\n page: Page,\n): Promise<BrowserBridgeClient> {\n const bridgeExists = async (): Promise<boolean> =>\n page.evaluate(() =>\n Boolean(\n (\n window as typeof window & {\n __dreamboardTestBridge__?: unknown;\n }\n ).__dreamboardTestBridge__,\n ),\n );\n\n const startedAt = Date.now();\n while (!(await bridgeExists())) {\n if (Date.now() - startedAt > DEFAULT_TIMEOUT_MS) {\n const bodyText = await page\n .locator(\"body\")\n .innerText()\n .catch(() => \"\");\n const diagnostic = bodyText.trim().replace(/\\s+/g, \" \").slice(0, 400);\n throw new Error(\n diagnostic.length > 0\n ? `Timed out waiting for browser test bridge. Page text: ${diagnostic}`\n : \"Timed out waiting for browser test bridge.\",\n );\n }\n await sleep(50);\n }\n\n return {\n snapshot: () =>\n page.evaluate(() =>\n (\n window as typeof window & {\n __dreamboardTestBridge__: {\n snapshot: () => Promise<BrowserSnapshot>;\n };\n }\n ).__dreamboardTestBridge__.snapshot(),\n ),\n submitInteraction: (playerId, interactionId, params) =>\n page.evaluate(\n ([nextPlayerId, nextInteractionId, nextParams]) =>\n (\n window as typeof window & {\n __dreamboardTestBridge__: {\n submitInteraction: (\n playerId: string,\n interactionId: string,\n params: unknown,\n ) => Promise<void>;\n };\n }\n ).__dreamboardTestBridge__.submitInteraction(\n nextPlayerId,\n nextInteractionId,\n nextParams,\n ),\n [playerId, interactionId, params] as const,\n ),\n waitForVersionChange: async (\n previousVersion,\n timeoutMs = DEFAULT_TIMEOUT_MS,\n ) => {\n const started = Date.now();\n while (Date.now() - started < timeoutMs) {\n const snapshot = await page.evaluate(() =>\n (\n window as typeof window & {\n __dreamboardTestBridge__: {\n snapshot: () => Promise<BrowserSnapshot>;\n };\n }\n ).__dreamboardTestBridge__.snapshot(),\n );\n if (snapshot.version > previousVersion) {\n return snapshot;\n }\n await sleep(50);\n }\n throw new Error(\"Timed out waiting for browser gameplay version change.\");\n },\n };\n}\n\nasync function assertLiveMatchesShadow(\n runner: TestRunnerName,\n shadow: ShadowReducerRuntime,\n live: GameplaySnapshot | BrowserSnapshot,\n): Promise<void> {\n if (runner === \"reducer\") {\n return;\n }\n\n const currentPhase =\n \"currentPhase\" in live ? live.currentPhase : shadow.phase();\n if (currentPhase !== shadow.phase()) {\n throw new Error(\n `Live phase '${String(currentPhase)}' diverged from reducer phase '${shadow.phase()}'.`,\n );\n }\n\n const livePlayerId =\n \"playerId\" in live ? live.playerId : live.controllingPlayerId;\n const liveView = \"view\" in live ? live.view : null;\n if (livePlayerId && !deepEqual(liveView, await shadow.view(livePlayerId))) {\n throw new Error(\"Live projected views diverged from reducer shadow views.\");\n }\n\n const liveInteractions =\n \"availableInteractions\" in live ? live.availableInteractions : null;\n if (\n livePlayerId &&\n liveInteractions &&\n !deepEqual(\n liveInteractions,\n shadow.availableInteractionsForPlayer(livePlayerId),\n )\n ) {\n throw new Error(\n \"Live available-interactions metadata diverged from reducer shadow state.\",\n );\n }\n}\n\nasync function loadBrowserDriver(\n projectRoot: string,\n): Promise<BrowserRunnerDriver | null> {\n const filePath = path.join(projectRoot, \"test\", \"browser-driver.ts\");\n if (!(await exists(filePath))) {\n return null;\n }\n const module = await importTypeScriptModule<BrowserDriverModule>(filePath);\n return module.default ?? module;\n}\n\nasync function openBrowserPage(\n playUrl: string,\n config: ResolvedConfig,\n): Promise<{\n browser: Browser;\n page: Page;\n}> {\n configurePlaywrightBrowsersPath();\n const { chromium } = await import(\"playwright\");\n const browser = await chromium.launch({ headless: true });\n const context = await browser.newContext({\n viewport: { width: 1440, height: 900 },\n });\n const initScript = await buildBrowserAuthInitScript(config);\n if (initScript) {\n await context.addInitScript({ content: initScript });\n }\n const page = await context.newPage();\n await page.goto(playUrl, { waitUntil: \"domcontentloaded\" });\n return { browser, page };\n}\n\nfunction sanitizeSnapshotSegment(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, \"-\");\n}\n\nfunction createScenarioSnapshotMatcher(options: {\n projectRoot: string;\n scenarioId: string;\n updateSnapshots: boolean;\n}): (filename: string | undefined, actual: unknown) => void {\n return (filename, actual) => {\n const suffix = filename ? `.${sanitizeSnapshotSegment(filename)}` : \"\";\n const snapshotPath = path.join(\n options.projectRoot,\n \"test\",\n \"generated\",\n \"snapshots\",\n `${sanitizeSnapshotSegment(options.scenarioId)}${suffix}.snapshot.json`,\n );\n const wrappedValue = {\n value: actual,\n };\n const serialized = `${JSON.stringify(wrappedValue, null, 2)}\\n`;\n\n mkdirSync(path.dirname(snapshotPath), { recursive: true });\n if (!existsSync(snapshotPath) || options.updateSnapshots) {\n writeFileSync(snapshotPath, serialized, \"utf8\");\n return;\n }\n\n const previous = JSON.parse(readFileSync(snapshotPath, \"utf8\")) as {\n value: unknown;\n };\n if (!deepEqual(previous.value, actual)) {\n throw new Error(\n `Snapshot mismatch for scenario '${options.scenarioId}'. Re-run with --update-snapshots to refresh ${path.relative(options.projectRoot, snapshotPath)}.`,\n );\n }\n };\n}\n\nasync function createScenarioContext(options: {\n runner: TestRunnerName;\n shadow: ShadowReducerRuntime;\n expect: ExpectApi;\n live?:\n | {\n sessionId: string;\n version: number;\n actionSetVersion: string;\n submitIndex?: number;\n diagnostics?: LiveReplayActionDiagnostic[];\n captureResponseBody?: boolean;\n }\n | undefined;\n actionPlan?:\n | {\n submitIndex?: number;\n diagnostics: LiveReplayActionDiagnostic[];\n }\n | undefined;\n remote?:\n | {\n sessionId: string;\n tracker: RemoteGameplayTracker;\n }\n | undefined;\n browser?:\n | {\n bridge: BrowserBridgeClient;\n driver: BrowserRunnerDriver | null;\n }\n | undefined;\n}): Promise<SharedScenarioContext> {\n const api: ScenarioGameApi = {\n start: async () => {\n await options.shadow.start();\n if (options.runner === \"remote\" && options.remote) {\n if (options.remote.tracker.hasLiveBootstrap()) {\n const live = options.remote.tracker.snapshot();\n await assertLiveMatchesShadow(\"remote\", options.shadow, live);\n } else {\n options.remote.tracker.applyShadow(options.shadow);\n }\n }\n if (options.runner === \"browser\" && options.browser) {\n const live = await options.browser.bridge.snapshot();\n await assertLiveMatchesShadow(\"browser\", options.shadow, live);\n }\n },\n patchState: async (mutator) => {\n await api.start();\n if (\n options.live ||\n options.remote ||\n options.browser ||\n options.actionPlan\n ) {\n throw new Error(\n \"game.patchState is only supported for reducer snapshot scenarios. Use it to materialize a state before --from-scenario or reducer tests, not inside live replay/browser runners.\",\n );\n }\n options.shadow.patchState(mutator);\n },\n submit: async (playerId, interactionId, params) => {\n await api.start();\n const interactionParams = params ?? {};\n const normalizedInputs =\n interactionParams &&\n typeof interactionParams === \"object\" &&\n !Array.isArray(interactionParams)\n ? (interactionParams as JsonObject)\n : {};\n\n const previousVersion = options.live\n ? options.live.version\n : options.actionPlan\n ? options.shadow.currentVersion()\n : options.runner === \"remote\"\n ? (options.remote?.tracker.snapshot().version ?? 0)\n : options.runner === \"browser\"\n ? ((await options.browser?.bridge.snapshot())?.version ?? 0)\n : 0;\n\n if (options.live) {\n if (!options.live.actionSetVersion) {\n options.live.actionSetVersion = await fetchLiveActionSetVersion(\n options.live.sessionId,\n playerId,\n );\n }\n const submittedActionSetVersion = options.live.actionSetVersion;\n const submitStartedAt = performance.now();\n const clientActionId = randomUUID();\n const { data, error, response } = await submitGameplayAuthorityAction({\n path: {\n sessionId: options.live.sessionId,\n playerId,\n interactionId,\n },\n body: {\n expectedVersion: previousVersion,\n actionSetVersion: options.live.actionSetVersion,\n inputs: normalizedInputs as never,\n },\n headers: { \"X-Dreamboard-Client-Action-Id\": clientActionId },\n });\n const durationMs = performance.now() - submitStartedAt;\n options.live.diagnostics?.push({\n index: options.live.submitIndex ?? 0,\n playerId,\n interactionId,\n inputs: normalizedInputs,\n expectedVersion: previousVersion,\n actionSetVersion: submittedActionSetVersion,\n responseStatus: response?.status,\n responseBody:\n options.live.captureResponseBody === false\n ? undefined\n : JSON.stringify(error ?? data ?? null),\n accepted: data?.accepted ?? undefined,\n errorCode:\n data?.accepted === false\n ? (data.errorCode ?? undefined)\n : error && typeof error === \"object\" && \"detail\" in error\n ? String((error as { detail?: unknown }).detail)\n : undefined,\n backendTiming:\n response?.headers?.get(\"server-timing\") ??\n response?.headers?.get(\"x-dreamboard-timing\") ??\n undefined,\n durationMs,\n });\n options.live.submitIndex = (options.live.submitIndex ?? 0) + 1;\n if (error) {\n throw createSubmissionError(\n \"api-error\",\n undefined,\n \"Failed to submit interaction\",\n );\n }\n if (data?.accepted === false) {\n const shadowError = await tryShadowSubmit(\n options.shadow,\n playerId,\n interactionId,\n interactionParams,\n );\n if (!shadowError || shadowError.errorCode !== data.errorCode) {\n throw new Error(\n \"Live session rejection diverged from reducer shadow state.\",\n );\n }\n throw createSubmissionError(\n data.errorCode ?? undefined,\n data.message ?? undefined,\n \"Interaction rejected\",\n );\n }\n options.live.version =\n typeof data?.version === \"number\"\n ? data.version\n : previousVersion + 1;\n options.live.actionSetVersion =\n data?.actionSetVersion ?? options.live.actionSetVersion;\n } else if (options.runner === \"remote\" && options.remote) {\n // Remote sessions submit through the gameplay-authority service, which\n // the in-memory authoring backend does not run. The remote runner\n // follows the reducer shadow below and asserts live snapshots instead.\n } else if (options.runner === \"browser\" && options.browser) {\n const handled =\n (await options.browser.driver?.interaction?.(options.browser.bridge, {\n playerId,\n interactionId,\n params: interactionParams,\n })) === true;\n if (!handled) {\n await options.browser.bridge.submitInteraction(\n playerId,\n interactionId,\n interactionParams,\n );\n }\n }\n\n await options.shadow.submitInteraction(\n playerId,\n interactionId,\n interactionParams,\n );\n\n if (options.actionPlan) {\n options.actionPlan.diagnostics.push({\n index: options.actionPlan.submitIndex ?? 0,\n playerId,\n interactionId,\n inputs: normalizedInputs,\n expectedVersion: previousVersion,\n actionSetVersion: \"\",\n accepted: true,\n durationMs: 0,\n });\n options.actionPlan.submitIndex =\n (options.actionPlan.submitIndex ?? 0) + 1;\n }\n\n if (options.runner === \"remote\" && options.remote) {\n options.remote.tracker.applyShadow(options.shadow);\n await assertLiveMatchesShadow(\n \"remote\",\n options.shadow,\n options.remote.tracker.snapshot(),\n );\n }\n if (options.runner === \"browser\" && options.browser) {\n const live =\n await options.browser.bridge.waitForVersionChange(previousVersion);\n await assertLiveMatchesShadow(\"browser\", options.shadow, live);\n }\n },\n };\n\n return {\n game: api,\n players: () => options.shadow.playerOrder(),\n seat: (index: number) => {\n const order = options.shadow.playerOrder();\n if (!Number.isInteger(index) || index < 0 || index >= order.length) {\n throw new Error(\n `seat(${index}) is out of range; scenario has ${order.length} player(s).`,\n );\n }\n return order[index]!;\n },\n state: () => options.shadow.phase(),\n view: (playerId) => options.shadow.view(playerId),\n interactions: (playerId) => options.shadow.interactionsForPlayer(playerId),\n explain: (playerId, interactionId) =>\n options.shadow.explain(playerId, interactionId),\n expect: options.expect,\n };\n}\n\nasync function tryShadowSubmit(\n shadow: ShadowReducerRuntime,\n playerId: string,\n interactionId: string,\n params: Record<string, unknown>,\n): Promise<SubmissionError | null> {\n try {\n await shadow.submitInteraction(playerId, interactionId, params);\n throw new Error(\"Expected shadow interaction to reject.\");\n } catch (error) {\n if (\n error instanceof Error &&\n (error as SubmissionError).name === \"SubmissionError\"\n ) {\n return error as SubmissionError;\n }\n throw error;\n }\n}\n\nexport async function createSessionFromScenario(options: {\n projectRoot: string;\n scenarioId: string;\n compiledResultId: string;\n projectId: string;\n gameId: string;\n debug?: boolean;\n trustGeneratedFingerprint?: boolean;\n}): Promise<SeededScenarioSession> {\n const startedAt = Date.now();\n const materialized = await materializeScenarioReducerState(options);\n const reducerHarnessMs = Date.now() - startedAt;\n const hydrateStartedAt = Date.now();\n const {\n data: snapshot,\n error,\n response,\n } = await createProjectSessionFromReducerSnapshot({\n path: { projectId: options.projectId },\n body: {\n compiledResultId: options.compiledResultId,\n seed: materialized.seed,\n playerCount: materialized.playerCount,\n setupProfileId: materialized.setupProfileId ?? undefined,\n baseId: materialized.baseId,\n scenarioId: materialized.scenarioId,\n reducerState: materialized.reducerState,\n reducerStateVersion: materialized.reducerStateVersion,\n fingerprintMetadata: materialized.fingerprintMetadata,\n },\n });\n const backendHydrateMs = Date.now() - hydrateStartedAt;\n if (error || !snapshot) {\n throw toDreamboardApiError(\n error,\n response,\n `Failed to materialize scenario '${options.scenarioId}' from reducer snapshot`,\n );\n }\n\n return {\n sessionId: snapshot.context.sessionId,\n shortCode: snapshot.context.shortCode,\n gameId: projectIdFromSessionGameSource(snapshot.context.gameSource),\n seed: materialized.seed,\n playerCount: materialized.playerCount,\n setupProfileId: materialized.setupProfileId,\n scenarioId: materialized.scenarioId,\n phase: materialized.phase,\n stage: materialized.stage,\n materialization: {\n mode: \"snapshot\",\n totalMs: Date.now() - startedAt,\n reducerHarnessMs,\n backendHydrateMs,\n },\n };\n}\n\nconst MATERIALIZED_SCENARIO_CACHE_VERSION = 1;\n\ntype MaterializedScenarioCachePayload = {\n cacheVersion: typeof MATERIALIZED_SCENARIO_CACHE_VERSION;\n fingerprintHash: string;\n materialized: MaterializedScenarioReducerState;\n};\n\ntype GeneratedScenarioManifestEntry = {\n id: string;\n base: string;\n};\n\nfunction materializedScenarioCachePath(options: {\n projectRoot: string;\n baseId: string;\n scenarioId: string;\n fingerprintHash: string;\n}): string {\n return path.join(\n options.projectRoot,\n PROJECT_DIR_NAME,\n \"dev\",\n \"scenario-cache\",\n `${sanitizeSnapshotSegment(options.baseId)}.${sanitizeSnapshotSegment(\n options.scenarioId,\n )}.${options.fingerprintHash}.json`,\n );\n}\n\nasync function readMaterializedScenarioCache(options: {\n projectRoot: string;\n baseId: string;\n scenarioId: string;\n fingerprintHash: string;\n}): Promise<MaterializedScenarioReducerState | null> {\n const cachePath = materializedScenarioCachePath(options);\n const text = await readTextFileIfExists(cachePath);\n if (!text) return null;\n try {\n const payload = JSON.parse(\n text,\n ) as Partial<MaterializedScenarioCachePayload>;\n if (\n payload.cacheVersion !== MATERIALIZED_SCENARIO_CACHE_VERSION ||\n payload.fingerprintHash !== options.fingerprintHash ||\n !payload.materialized\n ) {\n return null;\n }\n return payload.materialized;\n } catch {\n return null;\n }\n}\n\nasync function writeMaterializedScenarioCache(options: {\n projectRoot: string;\n baseId: string;\n scenarioId: string;\n fingerprintHash: string;\n materialized: MaterializedScenarioReducerState;\n}): Promise<void> {\n const cachePath = materializedScenarioCachePath(options);\n await ensureDir(path.dirname(cachePath));\n await writeJsonFile(cachePath, {\n cacheVersion: MATERIALIZED_SCENARIO_CACHE_VERSION,\n fingerprintHash: options.fingerprintHash,\n materialized: options.materialized,\n } satisfies MaterializedScenarioCachePayload);\n}\n\nexport async function materializeScenarioReducerState(options: {\n projectRoot: string;\n scenarioId: string;\n compiledResultId?: string;\n gameId?: string;\n debug?: boolean;\n trustGeneratedFingerprint?: boolean;\n}): Promise<MaterializedScenarioReducerState> {\n await ensureReducerNativeTestingFiles(options.projectRoot);\n let preloadedGeneratedBaseStates: BaseStateFile | null | undefined;\n if (options.trustGeneratedFingerprint === true) {\n const [generatedBaseStates, scenarioManifest] = await Promise.all([\n loadGeneratedBaseStates(options.projectRoot),\n loadGeneratedScenarioManifest(options.projectRoot),\n ]);\n preloadedGeneratedBaseStates = generatedBaseStates;\n const scenarioEntry = scenarioManifest.find(\n (entry) => entry.id === options.scenarioId,\n );\n const generatedBase = scenarioEntry\n ? generatedBaseStates?.[baseStateKey(scenarioEntry.base)]\n : null;\n if (\n generatedBase &&\n generatedBase.fingerprint.compiledResultId === options.compiledResultId &&\n generatedBase.fingerprint.gameId === options.gameId\n ) {\n const cached = await readMaterializedScenarioCache({\n projectRoot: options.projectRoot,\n baseId: scenarioEntry!.base,\n scenarioId: options.scenarioId,\n fingerprintHash: fingerprintHash(generatedBase.fingerprint),\n });\n if (cached) {\n return cached;\n }\n }\n }\n\n const [bases, scenarios, generatedBaseStates, manifest] = await Promise.all([\n loadTypedBases(options.projectRoot),\n loadTypedScenarios(options.projectRoot, {}),\n preloadedGeneratedBaseStates === undefined\n ? loadGeneratedBaseStates(options.projectRoot)\n : Promise.resolve(preloadedGeneratedBaseStates),\n loadManifest(options.projectRoot),\n ]);\n\n const matchingScenarios = scenarios.filter(\n (scenario) => scenario.definition.id === options.scenarioId,\n );\n if (matchingScenarios.length === 0) {\n throw new Error(\n `Unknown scenario '${options.scenarioId}'. Available scenarios: ${scenarios\n .map((scenario) => scenario.definition.id)\n .sort()\n .join(\", \")}`,\n );\n }\n if (matchingScenarios.length > 1) {\n throw new Error(\n `Scenario id '${options.scenarioId}' is defined more than once. Keep one scenario per file and one unique id per workspace.`,\n );\n }\n\n const scenario = matchingScenarios[0]!;\n const basesById = new Map(bases.map((base) => [base.definition.id, base]));\n validateTypedScenarioBases([scenario], basesById);\n const base = basesById.get(scenario.definition.from);\n if (!base) {\n throw new Error(\n `Missing typed base '${scenario.definition.from}' for scenario '${scenario.definition.id}'.`,\n );\n }\n\n const generatedBase = generatedBaseStates?.[baseStateKey(base.definition.id)];\n if (!generatedBase) {\n throw new Error(\n `Missing generated base artifact for '${base.definition.id}'. Run 'dreamboard test generate' before using --from-scenario.`,\n );\n }\n if (typeof generatedBase.version !== \"number\") {\n throw new Error(\n `Generated base artifact for '${base.definition.id}' is stale. Run 'dreamboard test generate' before using --from-scenario.`,\n );\n }\n\n const canTrustGeneratedFingerprint =\n options.trustGeneratedFingerprint === true &&\n generatedBase.fingerprint.compiledResultId === options.compiledResultId &&\n generatedBase.fingerprint.gameId === options.gameId;\n const current = canTrustGeneratedFingerprint\n ? generatedBase.fingerprint\n : await currentFingerprint({\n projectRoot: options.projectRoot,\n base,\n basesById,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n });\n if (!canTrustGeneratedFingerprint) {\n validateGeneratedFingerprint({\n generated: generatedBase.fingerprint,\n current,\n });\n }\n const currentHash = fingerprintHash(current);\n const cached = await readMaterializedScenarioCache({\n projectRoot: options.projectRoot,\n baseId: base.definition.id,\n scenarioId: scenario.definition.id,\n fingerprintHash: currentHash,\n });\n if (cached) {\n return cached;\n }\n\n const [gameModule, manifestContractModule] = await Promise.all([\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n ),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"shared\", \"manifest-contract.ts\"),\n ),\n ]);\n\n const createInitialTable =\n typeof manifestContractModule.createInitialTable === \"function\"\n ? (manifestContractModule.createInitialTable as GeneratedInitialTableFactory)\n : null;\n const resolvedBase = resolveBaseDefinition(base, basesById);\n const effectiveSetup = resolveEffectiveBaseSetup({\n manifest,\n base: base.definition,\n basesById,\n });\n const shadow = new ShadowReducerRuntime(\n manifest,\n gameModule.default,\n createInitialTable,\n resolvedBase.seed,\n resolvedBase.players,\n effectiveSetup.setupProfileId,\n options.debug ?? false,\n );\n shadow.hydrate(generatedBase.snapshot, generatedBase.version);\n\n const context = await createScenarioContext({\n runner: \"reducer\",\n shadow,\n expect: (await loadTestingExpectApiFactory())(),\n });\n\n shadow.clearHistory();\n await scenario.definition.when(context);\n if (\n scenario.definition.phase &&\n shadow.phase() !== scenario.definition.phase\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected phase '${scenario.definition.phase}' but reached '${shadow.phase()}'.`,\n );\n }\n if (\n scenario.definition.stage &&\n shadow.currentStage() !== scenario.definition.stage\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected stage '${scenario.definition.stage}' but reached '${\n shadow.currentStage() ?? \"null\"\n }'.`,\n );\n }\n\n const materialized: MaterializedScenarioReducerState = {\n baseId: base.definition.id,\n scenarioId: scenario.definition.id,\n seed: resolvedBase.seed,\n playerCount: resolvedBase.players,\n setupProfileId: effectiveSetup.setupProfileId,\n reducerState: shadow.rawState(),\n reducerStateVersion: shadow.currentVersion(),\n fingerprintMetadata: {\n baseFingerprintHash: fingerprintHash(generatedBase.fingerprint),\n currentFingerprintHash: fingerprintHash(current),\n baseBundleHash: generatedBase.fingerprint.baseBundleHash,\n manifestHash: generatedBase.fingerprint.manifestHash,\n appBundleHash: generatedBase.fingerprint.appBundleHash,\n uiContractHash: generatedBase.fingerprint.uiContractHash,\n baseId: base.definition.id,\n scenarioId: scenario.definition.id,\n },\n phase: shadow.phase(),\n stage: shadow.currentStage(),\n };\n await writeMaterializedScenarioCache({\n projectRoot: options.projectRoot,\n baseId: base.definition.id,\n scenarioId: scenario.definition.id,\n fingerprintHash: currentHash,\n materialized,\n });\n return materialized;\n}\n\nexport async function replayScenarioThroughBackend(options: {\n projectRoot: string;\n scenarioId: string;\n compiledResultId: string;\n gameId: string;\n debug?: boolean;\n captureResponseBody?: boolean;\n}): Promise<LiveReplayScenarioResult> {\n await ensureReducerNativeTestingFiles(options.projectRoot);\n\n const [\n bases,\n scenarios,\n generatedBaseStates,\n manifest,\n gameModule,\n manifestContractModule,\n ] = await Promise.all([\n loadTypedBases(options.projectRoot),\n loadTypedScenarios(options.projectRoot, {}),\n loadGeneratedBaseStates(options.projectRoot),\n loadManifest(options.projectRoot),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n ),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"shared\", \"manifest-contract.ts\"),\n ),\n ]);\n\n const matchingScenarios = scenarios.filter(\n (scenario) => scenario.definition.id === options.scenarioId,\n );\n if (matchingScenarios.length !== 1) {\n throw new Error(\n matchingScenarios.length === 0\n ? `Unknown scenario '${options.scenarioId}'. Available scenarios: ${scenarios\n .map((scenario) => scenario.definition.id)\n .sort()\n .join(\", \")}`\n : `Scenario id '${options.scenarioId}' is defined more than once. Keep one scenario per file and one unique id per workspace.`,\n );\n }\n\n const scenario = matchingScenarios[0]!;\n const basesById = new Map(bases.map((base) => [base.definition.id, base]));\n validateTypedScenarioBases([scenario], basesById);\n const base = basesById.get(scenario.definition.from);\n if (!base) {\n throw new Error(\n `Missing typed base '${scenario.definition.from}' for scenario '${scenario.definition.id}'.`,\n );\n }\n\n const generatedBase = generatedBaseStates?.[baseStateKey(base.definition.id)];\n if (!generatedBase) {\n throw new Error(\n `Missing generated base artifact for '${base.definition.id}'. Run 'dreamboard test generate' before replaying a scenario.`,\n );\n }\n validateGeneratedFingerprint({\n generated: generatedBase.fingerprint,\n current: await currentFingerprint({\n projectRoot: options.projectRoot,\n base,\n basesById,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n }),\n });\n\n const createInitialTable =\n typeof manifestContractModule.createInitialTable === \"function\"\n ? (manifestContractModule.createInitialTable as GeneratedInitialTableFactory)\n : null;\n const resolvedBase = resolveBaseDefinition(base, basesById);\n const effectiveSetup = resolveEffectiveBaseSetup({\n manifest,\n base: base.definition,\n basesById,\n });\n const shadow = new ShadowReducerRuntime(\n manifest,\n gameModule.default,\n createInitialTable,\n resolvedBase.seed,\n resolvedBase.players,\n effectiveSetup.setupProfileId,\n options.debug ?? false,\n );\n if (base.definition.extends) {\n const parentArtifact =\n generatedBaseStates?.[baseStateKey(base.definition.extends)];\n if (!parentArtifact || typeof parentArtifact.version !== \"number\") {\n throw new Error(\n `Base '${base.definition.id}' extends '${base.definition.extends}', but the parent artifact is missing or stale. Run 'dreamboard test generate' first.`,\n );\n }\n shadow.hydrate(parentArtifact.snapshot, parentArtifact.version);\n }\n\n const {\n data: session,\n error: sessionError,\n response: sessionResponse,\n } = await createProjectSession({\n path: { projectId: options.gameId },\n body: {\n compiledResultId: options.compiledResultId,\n seed: resolvedBase.seed,\n playerCount: resolvedBase.players,\n autoAssignSeats: true,\n setupProfileId: effectiveSetup.setupProfileId ?? undefined,\n },\n });\n if (!session || sessionError) {\n throw toDreamboardApiError(\n sessionError,\n sessionResponse,\n `Failed to create replay session for '${scenario.definition.id}'`,\n );\n }\n\n const { error: startError, response: startResponse } = await startGame({\n path: { sessionId: session.sessionId },\n });\n if (startError) {\n throw toDreamboardApiError(\n startError,\n startResponse,\n `Failed to start replay session for '${scenario.definition.id}'`,\n );\n }\n\n const diagnostics: LiveReplayActionDiagnostic[] = [];\n const context = await createScenarioContext({\n runner: \"reducer\",\n shadow,\n expect: (await loadTestingExpectApiFactory())(),\n live: {\n sessionId: session.sessionId,\n version: 0,\n actionSetVersion: \"\",\n submitIndex: 0,\n diagnostics,\n captureResponseBody: options.captureResponseBody,\n },\n });\n\n await context.game.start();\n await base.definition.setup({\n game: context.game,\n players: context.players,\n seat: context.seat,\n });\n shadow.clearHistory();\n await scenario.definition.when(context);\n if (\n scenario.definition.phase &&\n shadow.phase() !== scenario.definition.phase\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected phase '${scenario.definition.phase}' but reached '${shadow.phase()}'.`,\n );\n }\n if (\n scenario.definition.stage &&\n shadow.currentStage() !== scenario.definition.stage\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected stage '${scenario.definition.stage}' but reached '${\n shadow.currentStage() ?? \"null\"\n }'.`,\n );\n }\n\n return {\n sessionId: session.sessionId,\n shortCode: session.shortCode,\n gameId: projectIdFromSessionGameSource(session.gameSource),\n seed: resolvedBase.seed,\n playerCount: resolvedBase.players,\n setupProfileId: effectiveSetup.setupProfileId,\n scenarioId: scenario.definition.id,\n phase: shadow.phase(),\n stage: shadow.currentStage(),\n diagnostics,\n };\n}\n\nexport async function createScenarioActionPlan(options: {\n projectRoot: string;\n scenarioId: string;\n compiledResultId: string;\n gameId: string;\n debug?: boolean;\n}): Promise<LiveReplayActionPlan> {\n await ensureReducerNativeTestingFiles(options.projectRoot);\n\n const [\n bases,\n scenarios,\n generatedBaseStates,\n manifest,\n gameModule,\n manifestContractModule,\n ] = await Promise.all([\n loadTypedBases(options.projectRoot),\n loadTypedScenarios(options.projectRoot, {}),\n loadGeneratedBaseStates(options.projectRoot),\n loadManifest(options.projectRoot),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n ),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"shared\", \"manifest-contract.ts\"),\n ),\n ]);\n\n const matchingScenarios = scenarios.filter(\n (scenario) => scenario.definition.id === options.scenarioId,\n );\n if (matchingScenarios.length !== 1) {\n throw new Error(\n matchingScenarios.length === 0\n ? `Unknown scenario '${options.scenarioId}'. Available scenarios: ${scenarios\n .map((scenario) => scenario.definition.id)\n .sort()\n .join(\", \")}`\n : `Scenario id '${options.scenarioId}' is defined more than once. Keep one scenario per file and one unique id per workspace.`,\n );\n }\n\n const scenario = matchingScenarios[0]!;\n const basesById = new Map(bases.map((base) => [base.definition.id, base]));\n validateTypedScenarioBases([scenario], basesById);\n const base = basesById.get(scenario.definition.from);\n if (!base) {\n throw new Error(\n `Missing typed base '${scenario.definition.from}' for scenario '${scenario.definition.id}'.`,\n );\n }\n\n const generatedBase = generatedBaseStates?.[baseStateKey(base.definition.id)];\n if (!generatedBase) {\n throw new Error(\n `Missing generated base artifact for '${base.definition.id}'. Run 'dreamboard test generate' before replaying a scenario.`,\n );\n }\n validateGeneratedFingerprint({\n generated: generatedBase.fingerprint,\n current: await currentFingerprint({\n projectRoot: options.projectRoot,\n base,\n basesById,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n }),\n });\n\n const createInitialTable =\n typeof manifestContractModule.createInitialTable === \"function\"\n ? (manifestContractModule.createInitialTable as GeneratedInitialTableFactory)\n : null;\n const resolvedBase = resolveBaseDefinition(base, basesById);\n const effectiveSetup = resolveEffectiveBaseSetup({\n manifest,\n base: base.definition,\n basesById,\n });\n const shadow = new ShadowReducerRuntime(\n manifest,\n gameModule.default,\n createInitialTable,\n resolvedBase.seed,\n resolvedBase.players,\n effectiveSetup.setupProfileId,\n options.debug ?? false,\n );\n if (base.definition.extends) {\n const parentArtifact =\n generatedBaseStates?.[baseStateKey(base.definition.extends)];\n if (!parentArtifact || typeof parentArtifact.version !== \"number\") {\n throw new Error(\n `Base '${base.definition.id}' extends '${base.definition.extends}', but the parent artifact is missing or stale. Run 'dreamboard test generate' first.`,\n );\n }\n shadow.hydrate(parentArtifact.snapshot, parentArtifact.version);\n }\n\n const diagnostics: LiveReplayActionDiagnostic[] = [];\n const context = await createScenarioContext({\n runner: \"reducer\",\n shadow,\n expect: (await loadTestingExpectApiFactory())(),\n actionPlan: {\n submitIndex: 0,\n diagnostics,\n },\n });\n\n await context.game.start();\n await base.definition.setup({\n game: context.game,\n players: context.players,\n seat: context.seat,\n });\n shadow.clearHistory();\n await scenario.definition.when(context);\n if (\n scenario.definition.phase &&\n shadow.phase() !== scenario.definition.phase\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected phase '${scenario.definition.phase}' but reached '${shadow.phase()}'.`,\n );\n }\n if (\n scenario.definition.stage &&\n shadow.currentStage() !== scenario.definition.stage\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected stage '${scenario.definition.stage}' but reached '${\n shadow.currentStage() ?? \"null\"\n }'.`,\n );\n }\n\n return {\n gameId: options.gameId,\n seed: resolvedBase.seed,\n playerCount: resolvedBase.players,\n setupProfileId: effectiveSetup.setupProfileId,\n scenarioId: scenario.definition.id,\n phase: shadow.phase(),\n stage: shadow.currentStage(),\n diagnostics,\n };\n}\n\nexport async function replayActionPlanThroughBackend(options: {\n gameId: string;\n compiledResultId: string;\n seed: number;\n playerCount: number;\n setupProfileId?: string | null;\n scenarioId?: string;\n actions: ReadonlyArray<LiveReplayActionDiagnostic>;\n captureResponseBody?: boolean;\n}): Promise<LiveReplayScenarioResult> {\n const session = await createActionPlanReplaySession(options);\n return replayActionPlanInSession({\n session,\n actions: options.actions,\n captureResponseBody: options.captureResponseBody,\n });\n}\n\nexport async function createActionPlanReplaySession(options: {\n gameId: string;\n compiledResultId: string;\n seed: number;\n playerCount: number;\n setupProfileId?: string | null;\n scenarioId?: string;\n}): Promise<LiveReplayActionPlanSession> {\n const {\n data: session,\n error: sessionError,\n response: sessionResponse,\n } = await createProjectSession({\n path: { projectId: options.gameId },\n body: {\n compiledResultId: options.compiledResultId,\n seed: options.seed,\n playerCount: options.playerCount,\n autoAssignSeats: true,\n setupProfileId: options.setupProfileId ?? undefined,\n },\n });\n if (!session || sessionError) {\n throw toDreamboardApiError(\n sessionError,\n sessionResponse,\n \"Failed to create replay session from action plan\",\n );\n }\n\n const { error: startError, response: startResponse } = await startGame({\n path: { sessionId: session.sessionId },\n });\n if (startError) {\n throw toDreamboardApiError(\n startError,\n startResponse,\n \"Failed to start replay session from action plan\",\n );\n }\n\n return {\n sessionId: session.sessionId,\n shortCode: session.shortCode,\n gameId: projectIdFromSessionGameSource(session.gameSource),\n seed: options.seed,\n playerCount: options.playerCount,\n setupProfileId: options.setupProfileId ?? null,\n scenarioId: options.scenarioId ?? \"action-plan\",\n phase: null,\n stage: null,\n };\n}\n\nexport async function replayActionPlanInSession(options: {\n session: LiveReplayActionPlanSession;\n actions: ReadonlyArray<LiveReplayActionDiagnostic>;\n captureResponseBody?: boolean;\n actionIntervalMs?: number;\n actionJitterMs?: number;\n}): Promise<LiveReplayScenarioResult> {\n let version = 0;\n let actionSetVersion = \"\";\n const diagnostics: LiveReplayActionDiagnostic[] = [];\n for (const [index, action] of options.actions.entries()) {\n if (index > 0) {\n await waitForActionPacing({\n actionIntervalMs: options.actionIntervalMs ?? 0,\n actionJitterMs: options.actionJitterMs ?? 0,\n });\n }\n if (!actionSetVersion) {\n actionSetVersion = await fetchLiveActionSetVersion(\n options.session.sessionId,\n action.playerId,\n );\n }\n\n const submittedActionSetVersion = actionSetVersion;\n const submitStartedAt = performance.now();\n const clientActionId = randomUUID();\n const { data, error, response } = await submitGameplayAuthorityAction({\n path: {\n sessionId: options.session.sessionId,\n playerId: action.playerId,\n interactionId: action.interactionId,\n },\n body: {\n expectedVersion: version,\n actionSetVersion,\n inputs: action.inputs ?? {},\n },\n headers: { \"X-Dreamboard-Client-Action-Id\": clientActionId },\n });\n const durationMs = performance.now() - submitStartedAt;\n diagnostics.push({\n index,\n playerId: action.playerId,\n interactionId: action.interactionId,\n inputs: action.inputs ?? {},\n expectedVersion: version,\n actionSetVersion: submittedActionSetVersion,\n responseStatus: response?.status,\n responseBody:\n options.captureResponseBody === false\n ? undefined\n : JSON.stringify(error ?? data ?? null),\n accepted: data?.accepted ?? undefined,\n errorCode:\n data?.accepted === false\n ? (data.errorCode ?? undefined)\n : error && typeof error === \"object\" && \"detail\" in error\n ? String((error as { detail?: unknown }).detail)\n : undefined,\n backendTiming:\n response?.headers?.get(\"server-timing\") ??\n response?.headers?.get(\"x-dreamboard-timing\") ??\n undefined,\n durationMs,\n });\n\n if (error) {\n throw createSubmissionError(\n \"api-error\",\n undefined,\n \"Failed to submit interaction from action plan\",\n );\n }\n if (data?.accepted === false) {\n throw createSubmissionError(\n data.errorCode ?? undefined,\n data.message ?? undefined,\n \"Interaction rejected while replaying action plan\",\n );\n }\n version = typeof data?.version === \"number\" ? data.version : version + 1;\n actionSetVersion = data?.actionSetVersion ?? actionSetVersion;\n }\n\n return {\n ...options.session,\n diagnostics,\n };\n}\n\nasync function fetchLiveActionSetVersion(\n sessionId: string,\n playerId: string,\n): Promise<string> {\n const { data, error, response } = await getSessionSnapshot({\n path: { sessionId },\n query: { playerId },\n });\n if (error || !data || data.type !== \"gameplay\") {\n throw toDreamboardApiError(\n error ?? { detail: \"Gameplay snapshot was unavailable.\" },\n response,\n \"Failed to read live gameplay action set version\",\n );\n }\n return data.gameplay.actionSetVersion;\n}\n\nasync function waitForActionPacing(options: {\n actionIntervalMs: number;\n actionJitterMs: number;\n}): Promise<void> {\n const intervalMs = Math.max(0, options.actionIntervalMs);\n const jitterMs = Math.max(0, options.actionJitterMs);\n if (intervalMs === 0 && jitterMs === 0) {\n return;\n }\n const offsetMs =\n jitterMs === 0 ? 0 : Math.floor((Math.random() * 2 - 1) * jitterMs);\n const delayMs = Math.max(0, intervalMs + offsetMs);\n if (delayMs === 0) {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n}\n\nfunction baseStateKey(baseId: string): string {\n return baseId;\n}\n\nfunction fingerprintHash(\n fingerprint: BaseStateArtifact[\"fingerprint\"],\n): string {\n return hashContent(JSON.stringify(fingerprint));\n}\n\nfunction sortBasesForArtifacts(\n bases: LoadedBase[],\n basesById: Map<string, LoadedBase>,\n): LoadedBase[] {\n const ordered: LoadedBase[] = [];\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n const visit = (base: LoadedBase) => {\n if (visited.has(base.definition.id)) {\n return;\n }\n if (visiting.has(base.definition.id)) {\n throw new Error(\n `Cyclic reducer-native base inheritance detected at '${base.definition.id}'.`,\n );\n }\n visiting.add(base.definition.id);\n if (base.definition.extends) {\n const parent = basesById.get(base.definition.extends);\n if (!parent) {\n throw new Error(\n `Base '${base.definition.id}' extends unknown parent '${base.definition.extends}'.`,\n );\n }\n visit(parent);\n }\n visiting.delete(base.definition.id);\n visited.add(base.definition.id);\n ordered.push(base);\n };\n\n for (const base of bases) {\n visit(base);\n }\n\n return ordered;\n}\n\nfunction writeProjectionSnapshots(options: {\n projectRoot: string;\n baseId: string;\n shadow: ShadowReducerRuntime;\n}): void {\n const projectionDir = path.join(\n options.projectRoot,\n \"test\",\n \"generated\",\n \"bases\",\n options.baseId,\n );\n rmSync(projectionDir, { recursive: true, force: true });\n mkdirSync(projectionDir, { recursive: true });\n const projection = options.shadow.projectAllSeats();\n for (const [playerId, seatProjection] of Object.entries(projection.seats)) {\n const outputPath = path.join(projectionDir, `${playerId}.projection.json`);\n writeFileSync(\n outputPath,\n `${JSON.stringify(\n {\n currentStage: projection.currentStage,\n stageSeats: projection.stageSeats,\n ...seatProjection,\n },\n null,\n 2,\n )}\\n`,\n \"utf8\",\n );\n }\n}\n\nfunction validateTypedScenarioBases(\n scenarios: LoadedScenario[],\n basesById: Map<string, LoadedBase>,\n): void {\n const available = new Set(basesById.keys());\n const invalid = scenarios\n .filter((scenario) => !available.has(scenario.definition.from))\n .map(\n (scenario) =>\n path.relative(process.cwd(), scenario.filePath) +\n ` -> '${scenario.definition.from}'`,\n );\n\n if (invalid.length > 0) {\n throw new Error(\n `Unknown scenario base(s): ${invalid.join(\", \")}. Available bases: ${Array.from(available).sort().join(\", \")}`,\n );\n }\n}\n\nexport async function writeReducerNativeGeneratedFiles(options: {\n projectRoot: string;\n bases: LoadedBase[];\n scenarios: LoadedScenario[];\n compiledResultId?: string;\n gameId?: string;\n debug?: boolean;\n}): Promise<void> {\n await ensureReducerNativeTestingFiles(options.projectRoot);\n\n const manifest = await loadManifest(options.projectRoot);\n const manifestHash = hashContent(JSON.stringify(manifest));\n const appBundleHash = hashContent(\n await bundleTypeScriptModuleText(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n ),\n );\n const uiContractHash = hashContent(\n await bundleTypeScriptModuleText(\n path.join(options.projectRoot, \"shared\", \"generated\", \"ui-contract.ts\"),\n { external: SDK_UI_RUNTIME_EXTERNALS },\n ),\n );\n\n const generatedDir = path.join(options.projectRoot, \"test\", \"generated\");\n await ensureDir(generatedDir);\n const baseStates: BaseStateFile = {};\n const [gameModule, manifestContractModule] = await Promise.all([\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n ),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"shared\", \"manifest-contract.ts\"),\n ),\n ]);\n const createInitialTable =\n typeof manifestContractModule.createInitialTable === \"function\"\n ? (manifestContractModule.createInitialTable as GeneratedInitialTableFactory)\n : null;\n const contractFingerprintValue = contractFingerprint(\n gameModule.default as Parameters<typeof contractFingerprint>[0],\n ).value;\n const basesById = new Map(\n options.bases.map((base) => [base.definition.id, base]),\n );\n for (const base of sortBasesForArtifacts(options.bases, basesById)) {\n const resolvedBase = resolveBaseDefinition(base, basesById);\n const effectiveSetup = resolveEffectiveBaseSetup({\n manifest,\n base: base.definition,\n basesById,\n });\n const shadow = new ShadowReducerRuntime(\n manifest,\n gameModule.default,\n createInitialTable,\n resolvedBase.seed,\n resolvedBase.players,\n effectiveSetup.setupProfileId,\n options.debug ?? false,\n );\n let parentFingerprintHash: string | null = null;\n if (base.definition.extends) {\n const parentArtifact = baseStates[baseStateKey(base.definition.extends)];\n if (!parentArtifact) {\n throw new Error(\n `Base '${base.definition.id}' extends '${base.definition.extends}', but the parent artifact does not exist yet.`,\n );\n }\n if (parentArtifact.fingerprint.seed !== resolvedBase.seed) {\n throw new Error(\n `Base '${base.definition.id}' extends '${base.definition.extends}' but changes seed from ${parentArtifact.fingerprint.seed} to ${resolvedBase.seed}.`,\n );\n }\n if (parentArtifact.fingerprint.players !== resolvedBase.players) {\n throw new Error(\n `Base '${base.definition.id}' extends '${base.definition.extends}' but changes players from ${parentArtifact.fingerprint.players} to ${resolvedBase.players}.`,\n );\n }\n if (\n (parentArtifact.fingerprint.setupProfileId ?? null) !==\n (effectiveSetup.setupProfileId ?? null)\n ) {\n throw new Error(\n `Base '${base.definition.id}' extends '${base.definition.extends}' but changes setup profile from ${\n parentArtifact.fingerprint.setupProfileId ?? \"none\"\n } to ${effectiveSetup.setupProfileId ?? \"none\"}.`,\n );\n }\n parentFingerprintHash = fingerprintHash(parentArtifact.fingerprint);\n shadow.hydrate(parentArtifact.snapshot, parentArtifact.version);\n }\n const context = await createScenarioContext({\n runner: \"reducer\",\n shadow,\n expect: (await loadTestingExpectApiFactory())(),\n });\n await context.game.start();\n await base.definition.setup({\n game: context.game,\n players: context.players,\n seat: context.seat,\n });\n baseStates[baseStateKey(base.definition.id)] = {\n key: baseStateKey(base.definition.id),\n base: base.definition.id,\n snapshot: shadow.rawState(),\n version: shadow.currentVersion(),\n fingerprint: {\n base: base.definition.id,\n seed: resolvedBase.seed,\n players: resolvedBase.players,\n baseBundleHash: base.bundleHash,\n manifestHash,\n appBundleHash,\n uiContractHash,\n setupProfileId: effectiveSetup.setupProfileId,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n parentBaseId: base.definition.extends ?? null,\n parentFingerprintHash,\n contractFingerprint: contractFingerprintValue,\n },\n };\n writeProjectionSnapshots({\n projectRoot: options.projectRoot,\n baseId: base.definition.id,\n shadow,\n });\n }\n\n const header =\n \"// Generated by dreamboard test generate. Do not edit by hand.\\n\";\n await writeTextFile(\n path.join(generatedDir, \"base-states.generated.ts\"),\n `${header}export const BASE_STATES = ${JSON.stringify(baseStates, null, 2)} as const;\\nexport const BASE_STATES_CONTRACT_FINGERPRINT = ${JSON.stringify(contractFingerprintValue)};\\n`,\n );\n await writeTextFile(\n path.join(generatedDir, \"base-states.generated.d.ts\"),\n `${header}export declare const BASE_STATES: Record<string, unknown>;\\nexport declare const BASE_STATES_CONTRACT_FINGERPRINT: string | undefined;\\n`,\n );\n await writeTextFile(\n path.join(generatedDir, \"scenario-manifest.generated.ts\"),\n `${header}export const SCENARIO_MANIFEST = ${JSON.stringify(\n options.scenarios.map((scenario) => ({\n id: scenario.definition.id,\n filePath: path.relative(generatedDir, scenario.filePath),\n base: scenario.definition.from,\n runners: normalizeScenarioRunners(scenario.definition.runners),\n })),\n null,\n 2,\n )} as const;\\n`,\n );\n await writeJsonFile(path.join(generatedDir, \".generation-meta.json\"), {\n generatedAt: new Date().toISOString(),\n contractFingerprint: contractFingerprintValue,\n scenarioCount: options.scenarios.length,\n baseStateCount: options.bases.length,\n });\n}\n\nasync function loadGeneratedBaseStates(\n projectRoot: string,\n): Promise<BaseStateFile | null> {\n const filePath = path.join(\n projectRoot,\n \"test\",\n \"generated\",\n \"base-states.generated.ts\",\n );\n if (!(await exists(filePath))) {\n return null;\n }\n const module =\n await importTypeScriptModule<Record<string, unknown>>(filePath);\n return (module.BASE_STATES as BaseStateFile | undefined) ?? null;\n}\n\nasync function loadGeneratedScenarioManifest(\n projectRoot: string,\n): Promise<GeneratedScenarioManifestEntry[]> {\n const filePath = path.join(\n projectRoot,\n \"test\",\n \"generated\",\n \"scenario-manifest.generated.ts\",\n );\n if (!(await exists(filePath))) {\n return [];\n }\n const module =\n await importTypeScriptModule<Record<string, unknown>>(filePath);\n const entries = module.SCENARIO_MANIFEST;\n if (!Array.isArray(entries)) {\n return [];\n }\n return entries.flatMap((entry) => {\n if (\n entry &&\n typeof entry === \"object\" &&\n \"id\" in entry &&\n \"base\" in entry &&\n typeof entry.id === \"string\" &&\n typeof entry.base === \"string\"\n ) {\n return [{ id: entry.id, base: entry.base }];\n }\n return [];\n });\n}\n\nfunction validateGeneratedFingerprint(options: {\n generated: BaseStateArtifact[\"fingerprint\"];\n current: BaseStateArtifact[\"fingerprint\"];\n}): void {\n const mismatches: string[] = [];\n if (\n options.generated.contractFingerprint &&\n options.current.contractFingerprint &&\n options.generated.contractFingerprint !==\n options.current.contractFingerprint\n ) {\n const error = new Error(\n `Base states were generated for contract ${options.generated.contractFingerprint} but the current contract is ${options.current.contractFingerprint}. Remedy: run \\`dreamboard test generate\\`, then re-run the tests.`,\n );\n (error as Error & { code?: string }).code = STALE_CONTRACT_ARTIFACT_CODE;\n throw error;\n }\n if (options.generated.baseBundleHash !== options.current.baseBundleHash) {\n mismatches.push(\"base module changed\");\n }\n if (options.generated.manifestHash !== options.current.manifestHash) {\n mismatches.push(\"manifest changed\");\n }\n if (options.generated.appBundleHash !== options.current.appBundleHash) {\n mismatches.push(\"game reducer bundle changed\");\n }\n if (options.generated.uiContractHash !== options.current.uiContractHash) {\n mismatches.push(\"ui contract changed\");\n }\n if (\n options.generated.seed !== options.current.seed ||\n options.generated.players !== options.current.players\n ) {\n mismatches.push(\"base seed/player count changed\");\n }\n if (\n (options.generated.setupProfileId ?? null) !==\n (options.current.setupProfileId ?? null)\n ) {\n mismatches.push(\"base setup profile changed\");\n }\n if (\n (options.generated.parentBaseId ?? null) !==\n (options.current.parentBaseId ?? null)\n ) {\n mismatches.push(\"base parent changed\");\n }\n if (\n (options.generated.parentFingerprintHash ?? null) !==\n (options.current.parentFingerprintHash ?? null)\n ) {\n mismatches.push(\"parent base artifact changed\");\n }\n if (mismatches.length > 0) {\n throw new Error(\n `${mismatches.join(\"; \")}. Run 'dreamboard test generate' to refresh reducer-native base artifacts.`,\n );\n }\n}\n\nasync function currentFingerprint(options: {\n projectRoot: string;\n base: LoadedBase;\n basesById?: Map<string, LoadedBase>;\n compiledResultId?: string;\n gameId?: string;\n}): Promise<BaseStateArtifact[\"fingerprint\"]> {\n const manifest = await loadManifest(options.projectRoot);\n const gameModule = await importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n );\n const contractFingerprintValue = contractFingerprint(\n gameModule.default as Parameters<typeof contractFingerprint>[0],\n ).value;\n const resolvedBase = resolveBaseDefinition(\n options.base,\n options.basesById ?? new Map([[options.base.definition.id, options.base]]),\n );\n const effectiveSetup = resolveEffectiveBaseSetup({\n manifest,\n base: options.base.definition,\n basesById: options.basesById,\n });\n let parentFingerprintHash: string | null = null;\n if (options.base.definition.extends) {\n const parentBase = options.basesById?.get(options.base.definition.extends);\n if (!parentBase) {\n throw new Error(\n `Base '${options.base.definition.id}' extends unknown parent '${options.base.definition.extends}'.`,\n );\n }\n parentFingerprintHash = fingerprintHash(\n await currentFingerprint({\n projectRoot: options.projectRoot,\n base: parentBase,\n basesById: options.basesById,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n }),\n );\n }\n return {\n base: options.base.definition.id,\n seed: resolvedBase.seed,\n players: resolvedBase.players,\n baseBundleHash: options.base.bundleHash,\n manifestHash: hashContent(JSON.stringify(manifest)),\n appBundleHash: hashContent(\n await bundleTypeScriptModuleText(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n ),\n ),\n uiContractHash: hashContent(\n await bundleTypeScriptModuleText(\n path.join(options.projectRoot, \"shared\", \"generated\", \"ui-contract.ts\"),\n { external: SDK_UI_RUNTIME_EXTERNALS },\n ),\n ),\n setupProfileId: effectiveSetup.setupProfileId,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n parentBaseId: options.base.definition.extends ?? null,\n parentFingerprintHash,\n contractFingerprint: contractFingerprintValue,\n };\n}\n\nexport async function generateReducerNativeArtifacts(options: {\n projectRoot: string;\n compiledResultId?: string;\n gameId?: string;\n scenarioPath?: string;\n debug?: boolean;\n}): Promise<{\n bases: LoadedBase[];\n scenarios: LoadedScenario[];\n}> {\n await ensureReducerNativeTestingFiles(options.projectRoot);\n const [bases, scenarios] = await Promise.all([\n loadTypedBases(options.projectRoot),\n loadTypedScenarios(options.projectRoot, {\n scenarioPath: options.scenarioPath,\n }),\n ]);\n const basesById = new Map(bases.map((base) => [base.definition.id, base]));\n validateTypedScenarioBases(scenarios, basesById);\n await writeReducerNativeGeneratedFiles({\n projectRoot: options.projectRoot,\n bases,\n scenarios,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n debug: options.debug,\n });\n return { bases, scenarios };\n}\n\nexport async function runReducerNativeScenarios(options: {\n projectRoot: string;\n projectConfig: ProjectConfig;\n resolvedConfig: ResolvedConfig;\n runner: TestRunnerName;\n scenarioPath?: string;\n compiledResultId?: string;\n gameId?: string;\n webBaseUrl?: string;\n debug?: boolean;\n updateSnapshots?: boolean;\n}): Promise<ReducerNativeScenarioSummary> {\n await ensureReducerNativeTestingFiles(options.projectRoot);\n\n const [\n bases,\n scenarios,\n initialGeneratedBaseStates,\n manifest,\n gameModule,\n manifestContractModule,\n ] = await Promise.all([\n loadTypedBases(options.projectRoot),\n loadTypedScenarios(options.projectRoot, {\n scenarioPath: options.scenarioPath,\n }),\n loadGeneratedBaseStates(options.projectRoot),\n loadManifest(options.projectRoot),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"app\", \"game.ts\"),\n ),\n importTypeScriptModule<Record<string, unknown>>(\n path.join(options.projectRoot, \"shared\", \"manifest-contract.ts\"),\n ),\n ]);\n let generatedBaseStates = initialGeneratedBaseStates;\n const createInitialTable =\n typeof manifestContractModule.createInitialTable === \"function\"\n ? (manifestContractModule.createInitialTable as GeneratedInitialTableFactory)\n : null;\n\n const basesById = new Map(bases.map((base) => [base.definition.id, base]));\n validateTypedScenarioBases(scenarios, basesById);\n\n if (options.updateSnapshots) {\n await writeReducerNativeGeneratedFiles({\n projectRoot: options.projectRoot,\n bases,\n scenarios,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n debug: options.debug,\n });\n generatedBaseStates = await loadGeneratedBaseStates(options.projectRoot);\n }\n\n const runnerScenarios = scenarios.filter((scenario) =>\n normalizeScenarioRunners(scenario.definition.runners).includes(\n options.runner,\n ),\n );\n\n let browser: Browser | null = null;\n let page: Page | null = null;\n let browserBridge: BrowserBridgeClient | null = null;\n let browserDriver: BrowserRunnerDriver | null = null;\n\n if (options.runner === \"browser\") {\n const webBaseUrl = options.webBaseUrl ?? options.projectConfig.webBaseUrl;\n if (!webBaseUrl) {\n throw new Error(\n \"Browser runner requires a local webBaseUrl. Start the local web stack and configure the project for env local.\",\n );\n }\n browserDriver = await loadBrowserDriver(options.projectRoot);\n const opened = await openBrowserPage(\n `${webBaseUrl}/_dev`,\n options.resolvedConfig,\n );\n browser = opened.browser;\n page = opened.page;\n }\n\n try {\n let passed = 0;\n let failed = 0;\n const results: ReducerNativeScenarioResult[] = [];\n\n for (const scenario of runnerScenarios) {\n const base = basesById.get(scenario.definition.from);\n if (!base) {\n throw new Error(\n `Missing typed base '${scenario.definition.from}' for scenario '${scenario.definition.id}'.`,\n );\n }\n\n if (generatedBaseStates?.[baseStateKey(base.definition.id)]) {\n validateGeneratedFingerprint({\n generated:\n generatedBaseStates[baseStateKey(base.definition.id)]!.fingerprint,\n current: await currentFingerprint({\n projectRoot: options.projectRoot,\n base,\n basesById,\n compiledResultId: options.compiledResultId,\n gameId: options.gameId,\n }),\n });\n } else if (options.runner !== \"reducer\") {\n throw new Error(\n \"Missing reducer-native generated base artifacts. Run 'dreamboard test generate' first.\",\n );\n }\n\n try {\n const resolvedBase = resolveBaseDefinition(base, basesById);\n const effectiveSetup = resolveEffectiveBaseSetup({\n manifest,\n base: base.definition,\n basesById,\n });\n const shadow = new ShadowReducerRuntime(\n manifest,\n gameModule.default,\n createInitialTable,\n resolvedBase.seed,\n resolvedBase.players,\n effectiveSetup.setupProfileId,\n options.debug ?? false,\n );\n if (base.definition.extends) {\n const parentArtifact =\n generatedBaseStates?.[baseStateKey(base.definition.extends)];\n if (!parentArtifact) {\n throw new Error(\n `Base '${base.definition.id}' extends '${base.definition.extends}', but the parent artifact is missing. Run 'dreamboard test generate' first.`,\n );\n }\n shadow.hydrate(parentArtifact.snapshot, parentArtifact.version);\n }\n\n let remote:\n | {\n sessionId: string;\n tracker: RemoteGameplayTracker;\n }\n | undefined;\n if (options.runner === \"remote\") {\n const compiledResultId =\n options.compiledResultId ??\n options.projectConfig.compile?.latestSuccessful?.resultId;\n if (!compiledResultId) {\n throw new Error(\n \"Remote runner requires a compiled result. Compile the workspace first.\",\n );\n }\n const {\n data: session,\n error: sessionError,\n response: sessionResponse,\n } =\n await createProjectSession({\n path: { projectId: options.projectConfig.projectId },\n body: {\n compiledResultId,\n seed: resolvedBase.seed,\n playerCount: resolvedBase.players,\n autoAssignSeats: true,\n setupProfileId: effectiveSetup.setupProfileId ?? undefined,\n },\n });\n if (!session || sessionError) {\n throw toDreamboardApiError(\n sessionError,\n sessionResponse,\n \"Failed to create remote-runner session.\",\n );\n }\n const tracker = new RemoteGameplayTracker(\n session.sessionId,\n \"player-1\",\n );\n const { error: startError, response: startResponse } = await startGame({\n path: { sessionId: session.sessionId },\n });\n if (startError) {\n throw toDreamboardApiError(\n startError,\n startResponse,\n \"Failed to start remote-runner session.\",\n );\n }\n await tracker.bootstrap();\n remote = {\n sessionId: session.sessionId,\n tracker,\n };\n }\n\n if (options.runner === \"browser\" && page) {\n const compiledResultId =\n options.compiledResultId ??\n options.projectConfig.compile?.latestSuccessful?.resultId;\n if (!compiledResultId) {\n throw new Error(\n \"Browser runner requires a compiled result. Compile the workspace first.\",\n );\n }\n const {\n data: session,\n error: sessionError,\n response: sessionResponse,\n } =\n await createProjectSession({\n path: { projectId: options.projectConfig.projectId },\n body: {\n compiledResultId,\n seed: resolvedBase.seed,\n playerCount: resolvedBase.players,\n autoAssignSeats: true,\n setupProfileId: effectiveSetup.setupProfileId ?? undefined,\n },\n });\n if (!session || sessionError) {\n throw toDreamboardApiError(\n sessionError,\n sessionResponse,\n \"Failed to create browser-runner session.\",\n );\n }\n const { error: startError, data: started } = await startGame({\n path: { sessionId: session.sessionId },\n });\n if (startError || !started) {\n throw new Error(\"Failed to start browser-runner session.\");\n }\n await page.goto(\n `${options.webBaseUrl ?? options.projectConfig.webBaseUrl}/_dev/play/${started.context.shortCode}`,\n { waitUntil: \"domcontentloaded\" },\n );\n await waitForGameReady(page);\n browserBridge = await createBrowserBridgeClient(page);\n await browserDriver?.onReady?.(browserBridge);\n }\n\n const context = await createScenarioContext({\n runner: options.runner,\n shadow,\n expect: (await loadTestingExpectApiFactory())({\n matchSnapshot: createScenarioSnapshotMatcher({\n projectRoot: options.projectRoot,\n scenarioId: scenario.definition.id,\n updateSnapshots: options.updateSnapshots ?? false,\n }),\n }),\n remote,\n browser:\n options.runner === \"browser\" && browserBridge\n ? {\n bridge: browserBridge,\n driver: browserDriver,\n }\n : undefined,\n });\n\n await context.game.start();\n await base.definition.setup({\n game: context.game,\n players: context.players,\n seat: context.seat,\n });\n shadow.clearHistory();\n await scenario.definition.when(context);\n if (\n scenario.definition.phase &&\n shadow.phase() !== scenario.definition.phase\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected phase '${scenario.definition.phase}' but reached '${shadow.phase()}'.`,\n );\n }\n if (\n scenario.definition.stage &&\n shadow.currentStage() !== scenario.definition.stage\n ) {\n throw new Error(\n `Scenario '${scenario.definition.id}' expected stage '${scenario.definition.stage}' but reached '${\n shadow.currentStage() ?? \"null\"\n }'.`,\n );\n }\n await scenario.definition.then(context);\n passed += 1;\n results.push({\n id: scenario.definition.id,\n success: true,\n });\n } catch (error) {\n failed += 1;\n results.push({\n id: scenario.definition.id,\n success: false,\n errorCode: isStaleContractArtifactError(error)\n ? STALE_CONTRACT_ARTIFACT_CODE\n : undefined,\n error:\n error instanceof Error\n ? formatScenarioErrorForDisplay({\n error,\n projectRoot: options.projectRoot,\n scenarioFilePath: scenario.filePath,\n })\n : `Scenario '${scenario.definition.id}' failed.`,\n });\n }\n }\n\n return { passed, failed, results };\n } finally {\n if (browser) {\n await browser.close();\n }\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { createGameplayCapability } from \"@dreamboard-games/api-client\";\nimport {\n GameplayAuthorityRecoveringError,\n connectGameplayAuthority,\n} from \"@dreamboard-games/gameplay-authority-client\";\n\nconst CLIENT_ACTION_ID_HEADER = \"X-Dreamboard-Client-Action-Id\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport type SubmitGameplayAuthorityActionOptions = {\n path: {\n sessionId: string;\n playerId: string;\n interactionId: string;\n };\n body: {\n expectedVersion: number;\n actionSetVersion: string;\n inputs: Record<string, unknown>;\n };\n headers?: Record<string, string>;\n capabilityRequester?: typeof createGameplayCapability;\n connectAuthority?: typeof connectGameplayAuthority;\n clientActionIdFactory?: () => string;\n};\n\nexport type GameplayAuthorityActionSubmitResponse = {\n success: boolean;\n version: number;\n actionSetVersion: string;\n accepted?: boolean | null;\n durabilityStatus?: \"COMMITTED\" | null;\n errorCode?: string | null;\n message?: string | null;\n clientActionId?: string | null;\n};\n\nexport type SubmitGameplayAuthorityActionResult = {\n data?: GameplayAuthorityActionSubmitResponse;\n error?: unknown;\n response?: Response;\n};\n\nexport async function submitGameplayAuthorityAction(\n options: SubmitGameplayAuthorityActionOptions,\n): Promise<SubmitGameplayAuthorityActionResult> {\n try {\n const requestCapability =\n options.capabilityRequester ?? createGameplayCapability;\n const connectAuthority =\n options.connectAuthority ?? connectGameplayAuthority;\n const capability = await requestCapability({\n path: {\n sessionId: options.path.sessionId,\n playerId: options.path.playerId,\n },\n });\n if (capability.error || !capability.data) {\n return { error: capability.error ?? new Error(\"Missing capability.\") };\n }\n\n const clientActionId =\n options.headers?.[CLIENT_ACTION_ID_HEADER] ??\n options.clientActionIdFactory?.() ??\n randomUUID();\n const client = await connectAuthority({\n websocketUrl: capability.data.websocketUrl,\n capabilityToken: capability.data.token,\n openTimeoutMs: DEFAULT_TIMEOUT_MS,\n requestTimeoutMs: DEFAULT_TIMEOUT_MS,\n });\n\n try {\n const frame = await client.submitCommand({\n clientActionId,\n expectedVersion: options.body.expectedVersion,\n actionSetVersion: options.body.actionSetVersion,\n interactionId: options.path.interactionId,\n inputs: options.body.inputs ?? {},\n });\n if (frame.type === \"command.rejected\") {\n return {\n data: {\n success: false,\n accepted: false,\n version:\n typeof frame.currentVersion === \"number\"\n ? frame.currentVersion\n : options.body.expectedVersion,\n actionSetVersion: options.body.actionSetVersion,\n errorCode:\n typeof frame.errorCode === \"string\" ? frame.errorCode : undefined,\n message:\n typeof frame.message === \"string\" ? frame.message : undefined,\n clientActionId,\n },\n };\n }\n const acceptedVersion =\n typeof frame.version === \"number\" ? frame.version : undefined;\n if (acceptedVersion === undefined) {\n return {\n error: new Error(\"Accepted frame did not include a numeric version.\"),\n };\n }\n const update =\n frame.update && typeof frame.update === \"object\"\n ? (frame.update as Record<string, unknown>)\n : {};\n const view =\n update.view && typeof update.view === \"object\"\n ? (update.view as { actionSetVersion?: unknown })\n : {};\n const projectedActionSetVersion =\n typeof view.actionSetVersion === \"string\"\n ? view.actionSetVersion\n : undefined;\n return {\n data: {\n success: true,\n accepted: true,\n durabilityStatus: \"COMMITTED\",\n version: acceptedVersion,\n actionSetVersion:\n projectedActionSetVersion ?? options.body.actionSetVersion,\n clientActionId,\n },\n };\n } catch (error) {\n if (error instanceof GameplayAuthorityRecoveringError) {\n return {\n error: new Error(error.message || \"Session authority is recovering.\"),\n };\n }\n throw error;\n } finally {\n client.close();\n }\n } catch (error) {\n return { error };\n }\n}\n","import { z } from \"zod\";\nexport const GAMEPLAY_AUTHORITY_AUDIENCE = \"dreamboard-gameplay-authority\";\nexport const GAMEPLAY_TUNNEL_AUDIENCE = \"dreamboard-gameplay-authority-tunnel\";\nexport const GameplayPermissionSchema = z.enum([\n \"observe\",\n \"submit\",\n \"restore-history\",\n]);\nexport const GameplayConnectionContextSchema = z.object({\n sessionId: z.string().uuid(),\n playerId: z.string().min(1),\n permissions: z.array(GameplayPermissionSchema),\n});\nexport const GameplayActorKindSchema = z.enum([\"user\", \"demo\", \"perf\"]);\nexport const JsonPatchOperationSchema = z\n .object({\n op: z.string().min(1),\n path: z.string(),\n})\n .catchall(z.unknown());\nexport const ProjectedDeltaSchema = z.object({\n kind: z.literal(\"delta\"),\n generation: z.number().int().nonnegative(),\n baseVersion: z.number().int().nonnegative(),\n version: z.number().int().nonnegative(),\n patch: z.array(JsonPatchOperationSchema),\n});\nexport const ProjectedSnapshotSchema = z.object({\n kind: z.literal(\"snapshot\"),\n generation: z.number().int().nonnegative(),\n version: z.number().int().nonnegative(),\n view: z.unknown(),\n});\nconst BaseGameplayCapabilityClaimsSchema = z.object({\n typ: z.literal(\"gameplay-capability\"),\n aud: z.literal(GAMEPLAY_AUTHORITY_AUDIENCE),\n iss: z.string().min(1),\n exp: z.number().int().positive(),\n iat: z.number().int().positive().optional(),\n jti: z.string().min(1).optional(),\n sessionId: z.string().uuid(),\n playerId: z.string().min(1),\n permissions: z.array(GameplayPermissionSchema),\n});\nexport const UserGameplayCapabilityClaimsSchema = BaseGameplayCapabilityClaimsSchema.extend({\n actorKind: z.literal(\"user\"),\n});\nexport const DemoGameplayCapabilityClaimsSchema = BaseGameplayCapabilityClaimsSchema.extend({\n actorKind: z.literal(\"demo\"),\n});\nexport const PerfGameplayCapabilityClaimsSchema = BaseGameplayCapabilityClaimsSchema.extend({\n actorKind: z.literal(\"perf\"),\n perfRunId: z.string().uuid(),\n laneId: z.string().min(1),\n});\nexport const GameplayCapabilityClaimsSchema = z.discriminatedUnion(\"actorKind\", [\n UserGameplayCapabilityClaimsSchema,\n DemoGameplayCapabilityClaimsSchema,\n PerfGameplayCapabilityClaimsSchema,\n]);\nexport const GameplayTunnelClaimsSchema = z.object({\n aud: z.literal(GAMEPLAY_TUNNEL_AUDIENCE),\n iss: z.string().min(1),\n exp: z.number().int().positive(),\n iat: z.number().int().positive().optional(),\n jti: z.string().min(1).optional(),\n targetInstanceId: z.string().min(1),\n sessionId: z.string().uuid(),\n playerId: z.string().min(1),\n // Permissions are cryptographically bound into the tunnel token so the owner\n // task trusts the signed claim set rather than the unauthenticated\n // `tunnel.bind` frame. An ingress task cannot grant a player capabilities the\n // issued token did not attest.\n permissions: z.array(GameplayPermissionSchema),\n});\nexport const AuthConnectFrameSchema = z.object({\n type: z.literal(\"auth.connect\"),\n capabilityToken: z.string().min(1),\n});\nexport const AuthRefreshFrameSchema = z.object({\n type: z.literal(\"auth.refresh\"),\n capabilityToken: z.string().min(1),\n});\nexport const SessionResumeFrameSchema = z.object({\n type: z.literal(\"session.resume\"),\n lastSeenGeneration: z.number().int().nonnegative().nullable(),\n lastSeenVersion: z.number().int().nonnegative().nullable(),\n unacknowledgedClientActionIds: z.array(z.string().min(1)).max(32),\n});\nexport const CommandSubmitFrameSchema = z.object({\n type: z.literal(\"command.submit\"),\n clientActionId: z.string().min(1).max(128),\n expectedVersion: z.number().int().nonnegative(),\n actionSetVersion: z.string().min(1),\n interactionId: z.string().min(1),\n inputs: z.record(z.string(), z.unknown()),\n});\nexport const HistoryRestoreFrameSchema = z.object({\n type: z.literal(\"history.restore\"),\n restoreId: z.string().min(1).max(128),\n targetGeneration: z.number().int().nonnegative(),\n targetVersion: z.number().int().nonnegative(),\n});\nexport const ClientGameplayFrameSchema = z.discriminatedUnion(\"type\", [\n AuthConnectFrameSchema,\n AuthRefreshFrameSchema,\n SessionResumeFrameSchema,\n CommandSubmitFrameSchema,\n HistoryRestoreFrameSchema,\n]);\nexport const TunnelBindFrameSchema = z.object({\n type: z.literal(\"tunnel.bind\"),\n context: GameplayConnectionContextSchema,\n});\nexport const TunnelClientFrameSchema = z.discriminatedUnion(\"type\", [\n TunnelBindFrameSchema,\n SessionResumeFrameSchema,\n CommandSubmitFrameSchema,\n HistoryRestoreFrameSchema,\n]);\nexport const CommandAcceptedFrameSchema = z.object({\n type: z.literal(\"command.accepted\"),\n clientActionId: z.string().min(1),\n generation: z.number().int().nonnegative(),\n version: z.number().int().nonnegative(),\n stateHash: z.string().min(1),\n update: ProjectedSnapshotSchema,\n});\nexport const CommandRejectedFrameSchema = z.object({\n type: z.literal(\"command.rejected\"),\n clientActionId: z.string().min(1).optional(),\n errorCode: z.string().min(1),\n message: z.string().min(1),\n currentGeneration: z.number().int().nonnegative().optional(),\n currentVersion: z.number().int().nonnegative().optional(),\n});\nexport const HistoryRestoredFrameSchema = z.object({\n type: z.literal(\"history.restored\"),\n restoreId: z.string().min(1),\n generation: z.number().int().nonnegative(),\n version: z.number().int().nonnegative(),\n stateHash: z.string().min(1),\n update: ProjectedSnapshotSchema,\n});\nexport const HistoryRestoreRejectedFrameSchema = z.object({\n type: z.literal(\"history.restoreRejected\"),\n restoreId: z.string().min(1).optional(),\n errorCode: z.string().min(1),\n message: z.string().min(1),\n currentGeneration: z.number().int().nonnegative().optional(),\n currentVersion: z.number().int().nonnegative().optional(),\n});\nexport const AuthAcceptedFrameSchema = z.object({\n type: z.literal(\"auth.accepted\"),\n expiresAt: z.string().datetime(),\n});\nexport const AuthorityRecoveringFrameSchema = z.object({\n type: z.literal(\"authority.recovering\"),\n retryAfterMs: z.number().int().positive(),\n message: z.string().min(1),\n});\nexport const SessionSnapshotFrameSchema = z.object({\n type: z.literal(\"session.snapshot\"),\n generation: z.number().int().nonnegative(),\n version: z.number().int().nonnegative(),\n stateHash: z.string().min(1),\n update: ProjectedSnapshotSchema,\n});\nexport const SessionDeltaFrameSchema = z.object({\n type: z.literal(\"session.delta\"),\n clientActionId: z.string().min(1).optional(),\n update: ProjectedDeltaSchema,\n});\nexport const ServerGameplayFrameSchema = z.discriminatedUnion(\"type\", [\n AuthAcceptedFrameSchema,\n AuthorityRecoveringFrameSchema,\n SessionSnapshotFrameSchema,\n SessionDeltaFrameSchema,\n CommandAcceptedFrameSchema,\n CommandRejectedFrameSchema,\n HistoryRestoredFrameSchema,\n HistoryRestoreRejectedFrameSchema,\n]);\nexport const TunnelBoundFrameSchema = z.object({\n type: z.literal(\"tunnel.bound\"),\n sessionId: z.string().uuid(),\n playerId: z.string().min(1),\n});\nexport const TunnelServerFrameSchema = z.discriminatedUnion(\"type\", [\n TunnelBoundFrameSchema,\n AuthorityRecoveringFrameSchema,\n SessionSnapshotFrameSchema,\n SessionDeltaFrameSchema,\n CommandAcceptedFrameSchema,\n CommandRejectedFrameSchema,\n HistoryRestoredFrameSchema,\n HistoryRestoreRejectedFrameSchema,\n]);\n","import { ServerGameplayFrameSchema, } from \"@dreamboard-games/gameplay-authority-protocol\";\nconst DEFAULT_OPEN_TIMEOUT_MS = 5_000;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10_000;\nexport class GameplayAuthorityRecoveringError extends Error {\n retryAfterMs;\n constructor(message, retryAfterMs) {\n super(message);\n this.name = \"GameplayAuthorityRecoveringError\";\n this.retryAfterMs = retryAfterMs;\n }\n}\nexport async function connectGameplayAuthority(input) {\n const webSocketFactory = input.webSocketFactory ?? browserWebSocketFactory();\n const openTimeoutMs = input.openTimeoutMs ?? DEFAULT_OPEN_TIMEOUT_MS;\n const requestTimeoutMs = input.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n const socket = new webSocketFactory(input.websocketUrl, input.webSocketInit);\n try {\n await waitUntilOpen(socket, openTimeoutMs);\n socket.send(JSON.stringify({\n type: \"auth.connect\",\n capabilityToken: input.capabilityToken,\n }));\n await waitForServerFrame(socket, (frame) => frame.type === \"auth.accepted\", requestTimeoutMs);\n return new WebSocketGameplayAuthorityClient(socket, requestTimeoutMs);\n }\n catch (error) {\n socket.close();\n throw error;\n }\n}\nclass WebSocketGameplayAuthorityClient {\n socket;\n requestTimeoutMs;\n constructor(socket, requestTimeoutMs) {\n this.socket = socket;\n this.requestTimeoutMs = requestTimeoutMs;\n }\n resume(input = {}) {\n this.socket.send(JSON.stringify({\n type: \"session.resume\",\n lastSeenGeneration: input.lastSeenGeneration ?? null,\n lastSeenVersion: input.lastSeenVersion ?? null,\n unacknowledgedClientActionIds: input.unacknowledgedClientActionIds ?? [],\n }));\n }\n async submitCommand(input) {\n this.socket.send(JSON.stringify({\n type: \"command.submit\",\n clientActionId: input.clientActionId,\n expectedVersion: input.expectedVersion,\n actionSetVersion: input.actionSetVersion,\n interactionId: input.interactionId,\n inputs: input.inputs,\n }));\n const frame = await waitForServerFrame(this.socket, (candidate) => candidate.type === \"authority.recovering\" ||\n (candidate.type === \"command.accepted\" &&\n candidate.clientActionId === input.clientActionId) ||\n (candidate.type === \"command.rejected\" &&\n (candidate.clientActionId === undefined ||\n candidate.clientActionId === input.clientActionId)), this.requestTimeoutMs);\n throwIfRecovering(frame);\n if (frame.type !== \"command.accepted\" &&\n frame.type !== \"command.rejected\") {\n throw new Error(\"Unexpected gameplay authority command frame.\");\n }\n return frame;\n }\n async restoreHistory(input) {\n this.socket.send(JSON.stringify({\n type: \"history.restore\",\n restoreId: input.restoreId,\n targetGeneration: input.targetGeneration,\n targetVersion: input.targetVersion,\n }));\n const frame = await waitForServerFrame(this.socket, (candidate) => candidate.type === \"authority.recovering\" ||\n (candidate.type === \"history.restored\" &&\n candidate.restoreId === input.restoreId) ||\n (candidate.type === \"history.restoreRejected\" &&\n (candidate.restoreId === undefined ||\n candidate.restoreId === input.restoreId)), this.requestTimeoutMs);\n throwIfRecovering(frame);\n if (frame.type !== \"history.restored\" &&\n frame.type !== \"history.restoreRejected\") {\n throw new Error(\"Unexpected gameplay authority history frame.\");\n }\n return frame;\n }\n frames(signal) {\n return readServerFrames(this.socket, signal);\n }\n close() {\n this.socket.close();\n }\n}\nfunction throwIfRecovering(frame) {\n if (frame.type === \"authority.recovering\") {\n throw new GameplayAuthorityRecoveringError(frame.message, frame.retryAfterMs);\n }\n}\nfunction browserWebSocketFactory() {\n return BrowserGameplayAuthorityWebSocket;\n}\nclass BrowserGameplayAuthorityWebSocket {\n socket;\n listeners = new Map();\n constructor(url, init) {\n if (init?.headers && Object.keys(init.headers).length > 0) {\n throw new Error(\"Browser WebSocket does not support custom headers; provide a webSocketFactory for header-aware runtimes.\");\n }\n this.socket = new WebSocket(url);\n }\n send(data) {\n this.socket.send(data);\n }\n close() {\n this.socket.close();\n }\n on(event, listener) {\n const wrapped = (observed) => {\n if (event === \"message\" && \"data\" in observed) {\n listener(observed.data);\n return;\n }\n listener(observed);\n };\n const listeners = this.listeners.get(event) ?? new Map();\n listeners.set(listener, wrapped);\n this.listeners.set(event, listeners);\n this.socket.addEventListener(event, wrapped);\n }\n off(event, listener) {\n const listeners = this.listeners.get(event);\n const wrapped = listeners?.get(listener);\n if (!listeners || !wrapped) {\n return;\n }\n this.socket.removeEventListener(event, wrapped);\n listeners.delete(listener);\n }\n}\nasync function waitUntilOpen(socket, timeoutMs) {\n await waitForEvent(socket, \"open\", timeoutMs);\n}\nasync function waitForEvent(socket, event, timeoutMs) {\n return new Promise((resolve, reject) => {\n const cleanup = installSocketListeners(socket, {\n timeoutMs,\n onEvent(observed) {\n if (observed === event) {\n cleanup();\n resolve();\n }\n },\n onError(error) {\n cleanup();\n reject(error instanceof Error ? error : new Error(\"gameplay socket error\"));\n },\n onClose() {\n cleanup();\n reject(new Error(\"gameplay socket closed\"));\n },\n onTimeout() {\n cleanup();\n reject(new Error(\"gameplay socket timed out\"));\n },\n });\n });\n}\nasync function waitForServerFrame(socket, predicate, timeoutMs) {\n return new Promise((resolve, reject) => {\n const cleanup = installSocketListeners(socket, {\n timeoutMs,\n onMessage(data) {\n let frame;\n try {\n frame = ServerGameplayFrameSchema.parse(JSON.parse(messageToString(data)));\n }\n catch (error) {\n cleanup();\n reject(error instanceof Error\n ? error\n : new Error(\"invalid gameplay authority frame\"));\n return;\n }\n if (predicate(frame)) {\n cleanup();\n resolve(frame);\n }\n },\n onError(error) {\n cleanup();\n reject(error instanceof Error ? error : new Error(\"gameplay socket error\"));\n },\n onClose() {\n cleanup();\n reject(new Error(\"gameplay socket closed\"));\n },\n onTimeout() {\n cleanup();\n reject(new Error(\"gameplay socket timed out\"));\n },\n });\n });\n}\nfunction installSocketListeners(socket, handlers) {\n const timer = setTimeout(handlers.onTimeout, handlers.timeoutMs);\n const onOpen = () => handlers.onEvent?.(\"open\");\n const onMessage = (data) => handlers.onMessage?.(data);\n const onError = (error) => handlers.onError(error);\n const onClose = () => handlers.onClose();\n socket.on(\"open\", onOpen);\n socket.on(\"message\", onMessage);\n socket.on(\"error\", onError);\n socket.on(\"close\", onClose);\n return () => {\n clearTimeout(timer);\n socket.off?.(\"open\", onOpen);\n socket.off?.(\"message\", onMessage);\n socket.off?.(\"error\", onError);\n socket.off?.(\"close\", onClose);\n };\n}\nfunction readServerFrames(socket, signal) {\n const queue = [];\n let wake = null;\n let closed = false;\n let error = null;\n const wakeReader = () => {\n wake?.();\n wake = null;\n };\n const onMessage = (data) => {\n try {\n queue.push(ServerGameplayFrameSchema.parse(JSON.parse(messageToString(data))));\n }\n catch (candidate) {\n error =\n candidate instanceof Error\n ? candidate\n : new Error(\"invalid gameplay authority frame\");\n }\n wakeReader();\n };\n const onError = (candidate) => {\n error =\n candidate instanceof Error\n ? candidate\n : new Error(\"gameplay socket error\");\n wakeReader();\n };\n const onClose = () => {\n closed = true;\n wakeReader();\n };\n const onAbort = () => {\n closed = true;\n wakeReader();\n };\n socket.on(\"message\", onMessage);\n socket.on(\"error\", onError);\n socket.on(\"close\", onClose);\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n const cleanup = () => {\n socket.off?.(\"message\", onMessage);\n socket.off?.(\"error\", onError);\n socket.off?.(\"close\", onClose);\n signal?.removeEventListener(\"abort\", onAbort);\n };\n const iterator = {\n async next() {\n while (!closed && !signal?.aborted) {\n const next = queue.shift();\n if (next) {\n return { done: false, value: next };\n }\n if (error) {\n cleanup();\n throw error;\n }\n await new Promise((resolve) => {\n wake = resolve;\n });\n }\n cleanup();\n if (error) {\n throw error;\n }\n return { done: true, value: undefined };\n },\n async return(value) {\n closed = true;\n wakeReader();\n cleanup();\n return { done: true, value: value };\n },\n async throw(candidate) {\n closed = true;\n wakeReader();\n cleanup();\n throw candidate;\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n async [Symbol.asyncDispose]() {\n await this.return(undefined);\n },\n };\n return iterator;\n}\nfunction messageToString(data) {\n if (typeof data === \"string\") {\n return data;\n }\n if (data instanceof ArrayBuffer) {\n return new TextDecoder().decode(data);\n }\n if (ArrayBuffer.isView(data)) {\n return new TextDecoder().decode(data);\n }\n return String(data);\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport type { ResolvedConfig } from \"../types.js\";\n\n/**\n * Browser test runner helpers shared with reducer-native-test-harness (browser runner).\n * Screenshot / JSON scenario navigation helpers lived in the deleted `run` command.\n */\nexport function configurePlaywrightBrowsersPath(): void {\n if (process.env.PLAYWRIGHT_BROWSERS_PATH) {\n return;\n }\n\n const runtimeHome = process.env.HOME;\n let realHome: string;\n try {\n realHome = os.userInfo().homedir;\n } catch {\n return;\n }\n\n if (!runtimeHome || path.resolve(runtimeHome) === path.resolve(realHome)) {\n return;\n }\n\n const browserCachePath =\n process.platform === \"darwin\"\n ? path.join(realHome, \"Library\", \"Caches\", \"ms-playwright\")\n : process.platform === \"win32\"\n ? path.join(realHome, \"AppData\", \"Local\", \"ms-playwright\")\n : path.join(realHome, \".cache\", \"ms-playwright\");\n\n process.env.PLAYWRIGHT_BROWSERS_PATH = browserCachePath;\n}\n\nexport async function buildBrowserAuthInitScript(\n config: ResolvedConfig,\n): Promise<string | null> {\n if (!config.authToken) return null;\n\n return `(function(){localStorage.setItem('dreamboard_auth_token',${JSON.stringify(config.authToken)});})();`;\n}\n\nexport async function waitForGameReady(\n page: import(\"playwright\").Page,\n timeoutMs = 60000,\n): Promise<void> {\n await page.waitForSelector('iframe[title=\"Game UI Plugin\"]', {\n timeout: timeoutMs,\n });\n}\n","import type {\n GameTopologyManifest,\n SetupProfileSpec,\n} from \"@dreamboard-games/sdk/types\";\nimport { loadManifest } from \"../project/local-files.js\";\n\nexport type ResolvedSetupProfileSelection = {\n id: string | null;\n name: string | null;\n source: \"explicit\" | \"implicit-single\" | \"implicit-first\" | \"none\";\n};\n\nexport function resolveSetupProfileSelection(options: {\n manifest: GameTopologyManifest;\n requestedSetupProfileId?: string;\n}): ResolvedSetupProfileSelection {\n const setupProfiles: SetupProfileSpec[] =\n options.manifest.setupProfiles ?? [];\n const requestedSetupProfileId =\n options.requestedSetupProfileId?.trim() || undefined;\n\n if (requestedSetupProfileId) {\n const requestedProfile = setupProfiles.find(\n (profile) => profile.id === requestedSetupProfileId,\n );\n if (!requestedProfile) {\n const knownProfiles = setupProfiles\n .map((profile) => profile.id)\n .join(\", \");\n throw new Error(\n setupProfiles.length === 0\n ? `Unknown setup profile '${requestedSetupProfileId}'. The manifest defines no setup profiles.`\n : `Unknown setup profile '${requestedSetupProfileId}'. Expected one of: ${knownProfiles}.`,\n );\n }\n return {\n id: requestedProfile.id,\n name: requestedProfile.name,\n source: \"explicit\",\n };\n }\n\n if (setupProfiles.length === 0) {\n return {\n id: null,\n name: null,\n source: \"none\",\n };\n }\n\n if (setupProfiles.length === 1) {\n return {\n id: setupProfiles[0]?.id ?? null,\n name: setupProfiles[0]?.name ?? null,\n source: \"implicit-single\",\n };\n }\n\n return {\n id: setupProfiles[0]?.id ?? null,\n name: setupProfiles[0]?.name ?? null,\n source: \"implicit-first\",\n };\n}\n\nexport async function resolveSetupProfileSelectionForSession(options: {\n projectRoot: string;\n requestedSetupProfileId?: string;\n}): Promise<ResolvedSetupProfileSelection> {\n const manifest = await loadManifest(options.projectRoot);\n return resolveSetupProfileSelection({\n manifest,\n requestedSetupProfileId: options.requestedSetupProfileId,\n });\n}\n\nexport async function resolveSetupProfileIdForSession(options: {\n projectRoot: string;\n requestedSetupProfileId?: string;\n}): Promise<string | null> {\n return (\n await resolveSetupProfileSelectionForSession({\n projectRoot: options.projectRoot,\n requestedSetupProfileId: options.requestedSetupProfileId,\n })\n ).id;\n}\n","import type { SessionGameSource } from \"@dreamboard-games/api-client\";\n\nexport function projectIdFromSessionGameSource(\n source: SessionGameSource,\n): string {\n if (source.kind === \"USER_COMPILED\") {\n return source.projectId;\n }\n\n return `demo:${source.slug}:${source.revisionId}`;\n}\n"],"mappings":"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","names":["path","randomUUID","DEFAULT_TIMEOUT_MS","path","randomUUID","generatedBaseStates","generatedBase","cached","scenario","base"]}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
ensureProjectSdk,
|
|
4
|
-
loadRemoteProjectIdentity
|
|
5
|
-
} from "./chunk-KDBSVLCF.mjs";
|
|
6
|
-
import {
|
|
7
|
-
updateProjectState
|
|
8
|
-
} from "./chunk-776W3UGV.mjs";
|
|
9
|
-
|
|
10
|
-
// src/services/project/remote-project.ts
|
|
11
|
-
async function resolveRemoteProject(options) {
|
|
12
|
-
const identity = await loadRemoteProjectIdentity();
|
|
13
|
-
const project = await ensureProjectSdk({
|
|
14
|
-
projectId: options.projectConfig.projectId,
|
|
15
|
-
slug: options.projectConfig.slug,
|
|
16
|
-
updateAlias: options.updateAlias
|
|
17
|
-
});
|
|
18
|
-
const nextProjectConfig = {
|
|
19
|
-
...options.projectConfig,
|
|
20
|
-
slug: project.slug,
|
|
21
|
-
deploymentId: identity.deploymentId,
|
|
22
|
-
ownerScopeId: identity.ownerScopeId,
|
|
23
|
-
bindingKey: identity.bindingKey,
|
|
24
|
-
remoteHeadDigest: project.head?.revisionDigest,
|
|
25
|
-
apiBaseUrl: options.config.apiBaseUrl,
|
|
26
|
-
webBaseUrl: options.config.webBaseUrl
|
|
27
|
-
};
|
|
28
|
-
await updateProjectState(options.projectRoot, nextProjectConfig);
|
|
29
|
-
return {
|
|
30
|
-
identity,
|
|
31
|
-
project,
|
|
32
|
-
projectConfig: nextProjectConfig
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export {
|
|
37
|
-
resolveRemoteProject
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=chunk-QZH6IEZS.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/project/remote-project.ts"],"sourcesContent":["import type { Project } from \"@dreamboard-games/api-client\";\nimport { updateProjectState } from \"../../config/project-config.js\";\nimport type { ProjectConfig, ResolvedConfig } from \"../../types.js\";\nimport {\n ensureProjectSdk,\n loadRemoteProjectIdentity,\n type RemoteProjectIdentity,\n} from \"../api/index.js\";\n\nexport type ResolvedRemoteProject = {\n identity: RemoteProjectIdentity;\n project: Project;\n projectConfig: ProjectConfig;\n};\n\nexport async function resolveRemoteProject(options: {\n projectRoot: string;\n projectConfig: ProjectConfig;\n config: Pick<ResolvedConfig, \"apiBaseUrl\" | \"webBaseUrl\">;\n updateAlias?: boolean;\n}): Promise<ResolvedRemoteProject> {\n const identity = await loadRemoteProjectIdentity();\n const project = await ensureProjectSdk({\n projectId: options.projectConfig.projectId,\n slug: options.projectConfig.slug,\n updateAlias: options.updateAlias,\n });\n const nextProjectConfig: ProjectConfig = {\n ...options.projectConfig,\n slug: project.slug,\n deploymentId: identity.deploymentId,\n ownerScopeId: identity.ownerScopeId,\n bindingKey: identity.bindingKey,\n remoteHeadDigest: project.head?.revisionDigest,\n apiBaseUrl: options.config.apiBaseUrl,\n webBaseUrl: options.config.webBaseUrl,\n };\n\n await updateProjectState(options.projectRoot, nextProjectConfig);\n\n return {\n identity,\n project,\n projectConfig: nextProjectConfig,\n };\n}\n"],"mappings":";;;;;;;;;;AAeA,eAAsB,qBAAqB,SAKR;AACjC,QAAM,WAAW,MAAM,0BAA0B;AACjD,QAAM,UAAU,MAAM,iBAAiB;AAAA,IACrC,WAAW,QAAQ,cAAc;AAAA,IACjC,MAAM,QAAQ,cAAc;AAAA,IAC5B,aAAa,QAAQ;AAAA,EACvB,CAAC;AACD,QAAM,oBAAmC;AAAA,IACvC,GAAG,QAAQ;AAAA,IACX,MAAM,QAAQ;AAAA,IACd,cAAc,SAAS;AAAA,IACvB,cAAc,SAAS;AAAA,IACvB,YAAY,SAAS;AAAA,IACrB,kBAAkB,QAAQ,MAAM;AAAA,IAChC,YAAY,QAAQ,OAAO;AAAA,IAC3B,YAAY,QAAQ,OAAO;AAAA,EAC7B;AAEA,QAAM,mBAAmB,QAAQ,aAAa,iBAAiB;AAE/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/atomic-file.ts"],"sourcesContent":["/**\n * Primitives for safely mutating local state files owned by the CLI.\n *\n * Two guarantees:\n * - Writes are atomic-ish: we stage the payload in a sibling temp file with\n * the target permissions, fsync the contents, then `rename` over the target.\n * On POSIX `rename` within the same directory is atomic; on Windows it is\n * atomic within the same volume which is always the case for files we write\n * inside `~/.dreamboard`.\n * - We refuse to clobber a file with an empty payload. The original bug that\n * wiped refresh tokens on a failing `sync`/`compile` hinged on `undefined`\n * JSON values being persisted and reloaded as `{}`. Forbidding empty\n * writes here removes that entire failure mode at the primitive level.\n *\n * Additionally, `withFileLock` provides a cross-process advisory lock built on\n * `O_CREAT | O_EXCL` so that parallel CLI invocations (e.g. `dreamboard sync`\n * running while `dreamboard compile` is in flight) serialize around mutations\n * of the same credential state.\n */\n\nimport { constants as fsConstants, promises as fs, type Stats } from \"node:fs\";\nimport path from \"node:path\";\nimport crypto from \"node:crypto\";\n\nexport type AtomicWriteOptions = {\n /** File mode applied to the written file (default: 0o600). */\n mode?: number;\n /** Call `fsync` on the temp file before renaming. Default: true. */\n fsync?: boolean;\n};\n\nexport async function atomicWriteFile(\n targetPath: string,\n contents: string,\n options: AtomicWriteOptions = {},\n): Promise<void> {\n if (contents.length === 0) {\n throw new Error(\n `Refusing to atomicWriteFile an empty payload to ${targetPath}`,\n );\n }\n const mode = options.mode ?? 0o600;\n const shouldFsync = options.fsync ?? true;\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n\n const suffix = crypto.randomBytes(6).toString(\"hex\");\n const tmpPath = `${targetPath}.tmp-${process.pid}-${suffix}`;\n\n const fh = await fs.open(\n tmpPath,\n fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,\n mode,\n );\n try {\n await fh.writeFile(contents, \"utf8\");\n try {\n await fh.chmod(mode);\n } catch {\n // Some filesystems (e.g. network volumes, Windows) refuse chmod.\n // Ignoring here is safe: the `open` call above already created the\n // file with the requested mode on systems that honor it.\n }\n if (shouldFsync) {\n try {\n await fh.sync();\n } catch {\n // Best-effort. Not all backends (tmpfs on some platforms) support fsync.\n }\n }\n } finally {\n await fh.close();\n }\n\n try {\n await fs.rename(tmpPath, targetPath);\n } catch (err) {\n await fs.unlink(tmpPath).catch(() => undefined);\n throw err;\n }\n}\n\nexport type FileLockOptions = {\n /** Max number of acquisition attempts before giving up. Default: 100. */\n retries?: number;\n /** Minimum backoff between retries in ms. Default: 20. */\n minDelayMs?: number;\n /** Maximum backoff between retries in ms. Default: 200. */\n maxDelayMs?: number;\n /**\n * A lockfile older than this is considered stale and forcibly removed.\n * Guards against crashed processes leaving a permanent lock. Default: 30s.\n */\n staleMs?: number;\n};\n\nexport async function withFileLock<T>(\n lockPath: string,\n fn: () => Promise<T>,\n options: FileLockOptions = {},\n): Promise<T> {\n const retries = options.retries ?? 100;\n const minDelayMs = options.minDelayMs ?? 20;\n const maxDelayMs = options.maxDelayMs ?? 200;\n const staleMs = options.staleMs ?? 30_000;\n\n await fs.mkdir(path.dirname(lockPath), { recursive: true });\n\n let attempt = 0;\n let acquired = false;\n while (!acquired) {\n try {\n const fh = await fs.open(\n lockPath,\n fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,\n 0o600,\n );\n await fh.writeFile(`${process.pid}\\n`, \"utf8\");\n await fh.close();\n acquired = true;\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"EEXIST\") {\n throw err;\n }\n }\n\n let stat: Stats | null = null;\n try {\n stat = await fs.stat(lockPath);\n } catch {\n continue;\n }\n if (stat !== null) {\n const ageMs = Date.now() - stat.mtimeMs;\n if (ageMs > staleMs) {\n await fs.unlink(lockPath).catch(() => undefined);\n continue;\n }\n }\n\n attempt += 1;\n if (attempt >= retries) {\n throw new Error(\n `Timed out acquiring file lock at ${lockPath} after ${retries} attempts.`,\n );\n }\n const jitter = Math.floor(\n Math.random() * Math.max(1, maxDelayMs - minDelayMs),\n );\n await new Promise((resolve) => setTimeout(resolve, minDelayMs + jitter));\n }\n\n try {\n return await fn();\n } finally {\n await fs.unlink(lockPath).catch(() => undefined);\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/project/local-typecheck.ts"],"sourcesContent":["import { MANIFEST_TYPECHECK_CONFIG_FILE } from \"../../constants.js\";\nimport { spawn } from \"node:child_process\";\nimport { lstat } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\n\nexport type LocalTypecheckResult = {\n success: boolean;\n output: string;\n skipped?: boolean;\n};\n\ntype TypecheckRunner = {\n command: string;\n argsPrefix: string[];\n};\n\nconst TYPESCRIPT_BIN_PATH_SEGMENTS = [\n \"node_modules\",\n \"typescript\",\n \"bin\",\n \"tsc\",\n];\n\n// TypeScript shipped with the CLI package itself; used as a fallback when the\n// user's workspace does not provide its own `typescript` install.\nconst CLI_PACKAGE_TYPESCRIPT_CLI = resolveCliPackageTypescriptCli();\n\nfunction resolveCliPackageTypescriptCli(): string | null {\n try {\n const require = createRequire(import.meta.url);\n return require.resolve(\"typescript/bin/tsc\");\n } catch {\n return null;\n }\n}\n\nfunction getProjectNodeModules(projectRoot: string): string {\n return path.join(projectRoot, \"node_modules\");\n}\n\nfunction getProjectTypescriptCli(projectRoot: string): string {\n return path.join(projectRoot, ...TYPESCRIPT_BIN_PATH_SEGMENTS);\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n try {\n await lstat(targetPath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function ensureTypecheckDependencies(\n projectRoot: string,\n): Promise<string | null> {\n if (await pathExists(getProjectNodeModules(projectRoot))) {\n return null;\n }\n\n return `Skipping local typecheck: workspace dependencies are not installed at ${getProjectNodeModules(projectRoot)}. Run \\`dreamboard sync\\` to reconcile workspace dependencies first.`;\n}\n\nasync function resolveTypecheckRunner(\n projectRoot: string,\n): Promise<TypecheckRunner | null> {\n const localTypescriptCli = getProjectTypescriptCli(projectRoot);\n if (await pathExists(localTypescriptCli)) {\n return {\n command: process.execPath,\n argsPrefix: [localTypescriptCli],\n };\n }\n\n if (\n CLI_PACKAGE_TYPESCRIPT_CLI &&\n (await pathExists(CLI_PACKAGE_TYPESCRIPT_CLI))\n ) {\n return {\n command: process.execPath,\n argsPrefix: [CLI_PACKAGE_TYPESCRIPT_CLI],\n };\n }\n\n const globalTscAvailable = await new Promise<boolean>((resolve) => {\n const child = spawn(\"tsc\", [\"--version\"], {\n env: process.env,\n stdio: \"ignore\",\n });\n\n child.on(\"error\", () => {\n resolve(false);\n });\n child.on(\"close\", (code) => {\n resolve(code === 0);\n });\n });\n\n if (!globalTscAvailable) {\n return null;\n }\n\n return {\n command: \"tsc\",\n argsPrefix: [],\n };\n}\n\nasync function runTypecheckProject(\n runner: TypecheckRunner,\n projectRoot: string,\n projectPath: string,\n): Promise<LocalTypecheckResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(\n runner.command,\n [...runner.argsPrefix, \"--noEmit\", \"-p\", projectPath],\n {\n cwd: projectRoot,\n env: process.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n },\n );\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (chunk) => {\n stdout += chunk.toString();\n });\n child.stderr.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n child.on(\"error\", (error) => {\n reject(new Error(`Failed to start local typecheck. ${error.message}`));\n });\n child.on(\"close\", (code) => {\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n resolve({\n success: code === 0,\n output,\n });\n });\n });\n}\n\nexport async function runLocalTypecheck(\n projectRoot: string,\n): Promise<LocalTypecheckResult> {\n const dependencySkipReason = await ensureTypecheckDependencies(projectRoot);\n if (dependencySkipReason) {\n return {\n success: true,\n skipped: true,\n output: dependencySkipReason,\n };\n }\n\n const runner = await resolveTypecheckRunner(projectRoot);\n if (!runner) {\n return {\n success: true,\n skipped: true,\n output:\n \"Skipping local typecheck: TypeScript CLI was not found in workspace dependencies or on PATH.\",\n };\n }\n\n // The three projects are independent (no cross-project references), so\n // checking them in parallel roughly halves wall-clock time without changing\n // correctness. The slowest project (typically `ui/tsconfig.json`) bounds the\n // total cost.\n const results = await Promise.all(\n [\n MANIFEST_TYPECHECK_CONFIG_FILE,\n \"app/tsconfig.json\",\n \"ui/tsconfig.json\",\n ].map((projectPath) =>\n runTypecheckProject(runner, projectRoot, projectPath),\n ),\n );\n\n const firstFailure = results.find((result) => !result.success);\n if (firstFailure) {\n return firstFailure;\n }\n\n return {\n success: true,\n output: \"\",\n };\n}\n"],"mappings":"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","names":["require"]}
|