@dreamboard-games/cli 0.1.30-alpha.39 → 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.
Files changed (26) hide show
  1. package/dist/agent-verifier/agent-workspace-verifier.mjs +6 -6
  2. package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -1
  3. package/dist/agent-verifier/{chunk-WLUEMKVV.mjs → chunk-KAA3B4DI.mjs} +4 -4
  4. package/dist/agent-verifier/{chunk-WLUEMKVV.mjs.map → chunk-KAA3B4DI.mjs.map} +1 -1
  5. package/dist/agent-verifier/{chunk-M6YNQZCC.mjs → chunk-LROY5SN2.mjs} +4 -33
  6. package/dist/agent-verifier/chunk-LROY5SN2.mjs.map +1 -0
  7. package/dist/agent-verifier/{materialize-workspace-RPWQ5PST.mjs → materialize-workspace-JBDL6LF4.mjs} +4 -5
  8. package/dist/agent-verifier/materialize-workspace-JBDL6LF4.mjs.map +1 -0
  9. package/dist/agent-verifier/{reducer-native-test-harness-UFMSNNDY.mjs → reducer-native-test-harness-XQUPIT5D.mjs} +20 -20
  10. package/dist/agent-verifier/reducer-native-test-harness-XQUPIT5D.mjs.map +1 -0
  11. package/dist/agent-verifier/{static-scaffold-4HXUM2S4.mjs → static-scaffold-U5DXE23S.mjs} +2 -2
  12. package/dist/authoring-compatibility-internal.js +1 -1
  13. package/dist/{chunk-IZ7N2NLZ.js → chunk-5IYJOVUA.js} +22 -32
  14. package/dist/chunk-5IYJOVUA.js.map +1 -0
  15. package/dist/{chunk-R6J3LAQY.js → chunk-USZAPMQ4.js} +8 -38
  16. package/dist/{chunk-R6J3LAQY.js.map → chunk-USZAPMQ4.js.map} +1 -1
  17. package/dist/index.js +12 -15
  18. package/dist/index.js.map +1 -1
  19. package/dist/internal.js +2 -2
  20. package/package.json +1 -1
  21. package/release/authoring-release-set.json +3 -3
  22. package/dist/agent-verifier/chunk-M6YNQZCC.mjs.map +0 -1
  23. package/dist/agent-verifier/materialize-workspace-RPWQ5PST.mjs.map +0 -1
  24. package/dist/agent-verifier/reducer-native-test-harness-UFMSNNDY.mjs.map +0 -1
  25. package/dist/chunk-IZ7N2NLZ.js.map +0 -1
  26. /package/dist/agent-verifier/{static-scaffold-4HXUM2S4.mjs.map → static-scaffold-U5DXE23S.mjs.map} +0 -0
@@ -41,7 +41,7 @@ var AUTHORING_RELEASE_SET = {
41
41
  "packages": {
42
42
  "cli": {
43
43
  "name": "@dreamboard-games/cli",
44
- "version": "0.1.30-alpha.39"
44
+ "version": "0.1.30-alpha.40"
45
45
  },
46
46
  "sdk": {
47
47
  "name": "@dreamboard-games/sdk",
@@ -53,7 +53,7 @@ var AUTHORING_RELEASE_SET = {
53
53
  },
54
54
  "devHost": {
55
55
  "name": "@dreamboard-games/dev-host",
56
- "version": "0.1.30-alpha.26"
56
+ "version": "0.1.30-alpha.27"
57
57
  }
58
58
  },
59
59
  "protocols": {
@@ -71,7 +71,7 @@ var AUTHORING_RELEASE_SET = {
71
71
  "portable": true
72
72
  },
73
73
  "packageManager": "pnpm@10.4.1",
74
- "releaseSetId": "sha256:99293016258deb0093af008665e467ea2bee5f28eb93faa1332441bef9fa62a4"
74
+ "releaseSetId": "sha256:b1ba68e0bd81fbf6c44d39665e716f5fba81342036f04f1d102b12da77c73f1c"
75
75
  };
76
76
 
77
77
  // src/services/project/static-scaffold.ts
@@ -718,4 +718,4 @@ export {
718
718
  migrateLegacyScenarioImports,
719
719
  resolveStaticAssetRoot
720
720
  };
721
- //# sourceMappingURL=chunk-WLUEMKVV.mjs.map
721
+ //# sourceMappingURL=chunk-KAA3B4DI.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/services/project/static-scaffold.ts","../../src/release/authoring-release-set.generated.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { readdir, readFile, rmdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { GameTopologyManifest } from \"@dreamboard-games/sdk/types\";\nimport { AUTHORING_RELEASE_SET } from \"../../release/authoring-release-set.js\";\nimport { REDUCER_TESTING_TYPES_WRAPPER_CONTENT } from \"../../templates/testing-types-content.js\";\nimport {\n MANIFEST_TYPECHECK_CONFIG_FILE,\n PROJECT_CONFIG_FILE,\n PROJECT_DIR_NAME,\n} from \"../../constants.js\";\nimport type { LocalMaintainerRegistryConfig } from \"../../types.js\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport { materializeManifest } from \"./manifest-authoring.js\";\nimport { isDynamicSeedPath } from \"./scaffold-ownership.js\";\nimport {\n normalizeOwnedProjectPath,\n readWorkspaceTextFile,\n readWorkspaceTextFileIfExists,\n removeWorkspacePath,\n resolveWorkspacePath,\n unlinkWorkspaceFile,\n workspacePathExists,\n writeWorkspaceTextFile,\n} from \"./workspace-path.js\";\nimport {\n FRAMEWORK_PNPM_OVERRIDES,\n FRAMEWORK_REACT_DEPENDENCIES,\n FRAMEWORK_ZOD_VERSION,\n} from \"./framework-dependencies.js\";\n\ntype StaticScaffoldMode = \"new\" | \"update\";\ntype StaticAssetEntry = {\n targetPath: string;\n content: string;\n};\ntype StaticScaffoldOptions = {\n localMaintainerRegistry?: LocalMaintainerRegistryConfig | null;\n};\ntype RootPackageJsonShape = {\n private?: boolean;\n packageManager?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n overrides?: Record<string, unknown>;\n pnpm?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nconst DREAMBOARD_SCAFFOLD_REFRESH_COMMAND =\n \"dreamboard project create or dreamboard project clone\";\nconst DREAMBOARD_GITIGNORE_BLOCK = [\n \"# Dreamboard local state\",\n \".dreamboard/state.json\",\n \".dreamboard/snapshot.json\",\n \".dreamboard/dev/\",\n \".dreamboard/generated/\",\n \"node_modules/\",\n \"ui/node_modules/\",\n \"\",\n].join(\"\\n\");\nconst TESTING_TYPES_STUB =\n \"export function defineScenario(scenario) { return scenario; }\\n\";\nconst GENERATED_TESTING_TYPES_PREFIX = \"// Generated by dreamboard\";\nconst GENERATED_SCENARIO_PREFIX = \"// Generated by dreamboard scaffold.\";\nconst LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT = `export {\n ErrorBoundary,\n type ErrorBoundaryProps,\n} from \"@dreamboard-games/sdk/ui\";\nexport { PluginRuntime, type PluginRuntimeProps } from \"@dreamboard-games/sdk/runtime\";\n`;\nconst OLD_LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT = [\n \"export {\",\n \" ErrorBoundary,\",\n \" PluginRuntime,\",\n \" type ErrorBoundaryProps,\",\n \" type PluginRuntimeProps,\",\n `} from \"@dreamboard/ui-${\"sdk\"}\";`,\n \"\",\n].join(\"\\n\");\nconst OLD_PUBLIC_DREAMBOARD_COMPONENT_INDEX_CONTENT = [\n \"export {\",\n \" ErrorBoundary,\",\n \" PluginRuntime,\",\n \" type ErrorBoundaryProps,\",\n \" type PluginRuntimeProps,\",\n `} from \"@dreamboard-games/ui-${\"sdk\"}\";`,\n \"\",\n].join(\"\\n\");\nconst INITIAL_SCENARIO_CONTENT = `${GENERATED_SCENARIO_PREFIX}\nimport { defineScenario } from \"../testing-types\";\n\nexport default defineScenario({\n id: \"smoke-initial-turn\",\n description:\n \"Sanity check that the scaffolded workspace boots into its initial phase.\",\n from: \"initial-turn\",\n when: async () => undefined,\n then: ({ expect, players, state }) => {\n const playerIds = players();\n expect(playerIds).toHaveLength(playerIds.length);\n expect(playerIds.length).toBeGreaterThanOrEqual(1);\n expect(state()).toBe(\"setup\");\n },\n});\n`;\nconst STATIC_ASSET_ROOT = resolveStaticAssetRoot();\nconst SDK_DEPENDENCY_RANGES = {\n \"@dreamboard-games/sdk\": AUTHORING_RELEASE_SET.packages.sdk.version,\n} as const;\nconst DEV_HOST_DEPENDENCY_RANGES = {\n \"@dreamboard-games/dev-host\": AUTHORING_RELEASE_SET.packages.devHost.version,\n} as const;\nconst DREAMBOARD_PACKAGE_OVERRIDES = {\n \"@dreamboard-games/api-client\":\n AUTHORING_RELEASE_SET.packages.apiClient.version,\n \"@dreamboard-games/dev-host\": AUTHORING_RELEASE_SET.packages.devHost.version,\n \"@dreamboard-games/sdk\": AUTHORING_RELEASE_SET.packages.sdk.version,\n} as const;\n\nconst FRAMEWORK_SCRIPTS = {\n dev: \"dreamboard dev\",\n \"test:ui\":\n \"tsx --tsconfig test/tsconfig.tsx-runtime.json --test test/ui/**/*.test.tsx\",\n typecheck: `tsc --noEmit -p ${MANIFEST_TYPECHECK_CONFIG_FILE} && tsc --noEmit -p app/tsconfig.json && tsc --noEmit -p ui/tsconfig.json`,\n \"typecheck:manifest\": `tsc --noEmit -p ${MANIFEST_TYPECHECK_CONFIG_FILE}`,\n \"typecheck:app\": \"tsc --noEmit -p app/tsconfig.json\",\n \"typecheck:ui\": \"tsc --noEmit -p ui/tsconfig.json\",\n} as const;\nconst SHARED_DEPENDENCIES = {\n ...FRAMEWORK_REACT_DEPENDENCIES,\n} as const;\nconst ROOT_APP_DEPENDENCIES = {\n zod: FRAMEWORK_ZOD_VERSION,\n} as const;\nconst SHARED_DEV_DEPENDENCIES = {\n typescript: \"^5.9.2\",\n \"@types/node\": \"^24.5.2\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n csstype: \"^3.1.3\",\n tsx: \"^4.20.5\",\n} as const;\n\nexport async function scaffoldStaticWorkspace(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions = {},\n): Promise<void> {\n await writeFrameworkStaticFiles(projectRoot, mode, options);\n await ensureDreamboardGitignore(projectRoot);\n await writeManifestTypecheckTsconfig(projectRoot);\n await removeLegacyVendoredSdkPaths(projectRoot);\n await removeLegacyDreamboardComponentPath(projectRoot);\n\n await ensureDir(resolveWorkspacePath(projectRoot, \"test/bases\"));\n await ensureDir(resolveWorkspacePath(projectRoot, \"test/scenarios\"));\n await ensureDir(resolveWorkspacePath(projectRoot, \"test/generated\"));\n\n await writeTestReadme(projectRoot);\n await writeGeneratedTestingStubs(projectRoot, mode);\n const initialTestPlayerCount = await inferInitialTestPlayerCount(projectRoot);\n await writeInitialBase(projectRoot, mode, initialTestPlayerCount);\n await writeInitialScenario(projectRoot, mode);\n await writeTestingTypes(projectRoot, mode);\n await writeTestTsconfig(projectRoot);\n\n if (await workspacePathExists(projectRoot, \"test/testing-types.d.ts\")) {\n await unlinkWorkspaceFile(projectRoot, \"test/testing-types.d.ts\");\n }\n if (await workspacePathExists(projectRoot, \"test/base-scenarios.json\")) {\n await unlinkWorkspaceFile(projectRoot, \"test/base-scenarios.json\");\n }\n\n await migrateLegacyScenarioImports(projectRoot);\n}\n\nasync function ensureDreamboardGitignore(projectRoot: string): Promise<void> {\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n \".gitignore\",\n );\n if (existing?.includes(\".dreamboard/state.json\")) {\n return;\n }\n await writeWorkspaceTextFile(\n projectRoot,\n \".gitignore\",\n `${existing ? `${existing.trimEnd()}\\n\\n` : \"\"}${DREAMBOARD_GITIGNORE_BLOCK}`,\n );\n}\n\nexport async function assertCliStaticScaffoldComplete(\n projectRoot: string,\n deletedPaths: readonly string[] = [],\n): Promise<void> {\n const expectedEntries = await getExpectedStaticEntries(projectRoot);\n const missingOrBlankPaths: string[] = [];\n\n for (const entry of expectedEntries) {\n const content = await readWorkspaceTextFileIfExists(\n projectRoot,\n entry.targetPath,\n );\n\n if (content === null || content.trim().length === 0) {\n missingOrBlankPaths.push(entry.targetPath);\n }\n }\n\n const staticPaths = new Set(expectedEntries.map((entry) => entry.targetPath));\n const deletedStaticPaths = deletedPaths\n .map(normalizeOwnedProjectPath)\n .filter(\n (filePath): filePath is string =>\n filePath !== null && staticPaths.has(filePath),\n )\n .sort();\n\n if (missingOrBlankPaths.length === 0 && deletedStaticPaths.length === 0) {\n return;\n }\n\n const problems: string[] = [];\n if (missingOrBlankPaths.length > 0) {\n problems.push(\n `missing or blank: ${summarizePaths(missingOrBlankPaths.sort())}`,\n );\n }\n if (deletedStaticPaths.length > 0) {\n problems.push(`deleted: ${summarizePaths(deletedStaticPaths)}`);\n }\n\n throw new Error(\n `CLI static scaffold is incomplete (${problems.join(\"; \")}). Refresh the project scaffold with ${DREAMBOARD_SCAFFOLD_REFRESH_COMMAND} before building or testing.`,\n );\n}\n\nasync function writeFrameworkStaticFiles(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions,\n): Promise<void> {\n const assetEntries = await getStaticAssetEntries();\n\n for (const entry of assetEntries) {\n // Dynamic seed files are user-customizable: only write them on first\n // scaffold; preserve existing content on subsequent updates.\n if (mode === \"update\" && isDynamicSeedPath(entry.targetPath)) {\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n entry.targetPath,\n );\n if (existing !== null && existing.trim().length > 0) {\n continue;\n }\n }\n await writeWorkspaceTextFile(projectRoot, entry.targetPath, entry.content);\n }\n\n for (const entry of await getDynamicStaticEntries(\n projectRoot,\n mode,\n options,\n )) {\n await writeWorkspaceTextFile(projectRoot, entry.targetPath, entry.content);\n }\n\n if (!options.localMaintainerRegistry) {\n await removeWorkspacePath(projectRoot, \".npmrc\", { force: true });\n }\n}\n\nasync function removeLegacyVendoredSdkPaths(\n projectRoot: string,\n): Promise<void> {\n await removeWorkspacePath(projectRoot, \"app/sdk\", {\n recursive: true,\n force: true,\n });\n await removeWorkspacePath(projectRoot, \"ui/sdk\", {\n recursive: true,\n force: true,\n });\n}\n\nasync function removeLegacyDreamboardComponentPath(\n projectRoot: string,\n): Promise<void> {\n const legacyIndexProjectPath = \"ui/components/dreamboard/index.ts\";\n const legacyDirPath = resolveWorkspacePath(\n projectRoot,\n \"ui/components/dreamboard\",\n );\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n legacyIndexProjectPath,\n );\n\n const removableLegacyContents = new Set([\n LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT.trim(),\n OLD_LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT.trim(),\n OLD_PUBLIC_DREAMBOARD_COMPONENT_INDEX_CONTENT.trim(),\n ]);\n\n if (existing === null || !removableLegacyContents.has(existing.trim())) {\n return;\n }\n\n await unlinkWorkspaceFile(projectRoot, legacyIndexProjectPath);\n const remainingEntries = await readdir(legacyDirPath).catch(() => []);\n if (remainingEntries.length === 0) {\n await rmdir(legacyDirPath);\n }\n}\n\nasync function writeTestReadme(projectRoot: string): Promise<void> {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/README.md\",\n \"# Dreamboard Test Workspace\\n\\nTypeScript bases live in `test/bases/*.base.ts` and scenarios live in `test/scenarios/*.scenario.ts`.\\n\\n1. Define reusable seeded bases with `defineBase({ id, seed, players, setupProfileId?, setup })`.\\n2. Define scenarios with `defineScenario({ id, from, when, then })`.\\n3. Scenario assertions can read `players()`, `state()`, `view(playerId)`, and `interactions(playerId)`.\\n4. Run deterministic scenario tests: `dreamboard test`.\\n5. Run a single scenario when needed: `dreamboard test --scenario <scenario-id>`.\\n\\nImport test helpers from `../testing-types`.\\n\\nGenerated artifacts are written to `test/generated/*` and should not be edited manually.\\n\",\n );\n}\n\nasync function writeInitialBase(\n projectRoot: string,\n mode: StaticScaffoldMode,\n players: number,\n): Promise<void> {\n if (mode === \"update\") {\n return;\n }\n\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/bases/initial-turn.base.ts\",\n `import { defineBase } from \"../testing-types\";\n\nexport default defineBase({\n id: \"initial-turn\",\n seed: 1337,\n players: ${players},\n setup: async () => undefined,\n});\n`,\n );\n}\n\nasync function writeInitialScenario(\n projectRoot: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n if (mode === \"new\") {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/scenarios/smoke-initial-turn.scenario.ts\",\n INITIAL_SCENARIO_CONTENT,\n );\n return;\n }\n\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n \"test/scenarios/smoke-initial-turn.scenario.ts\",\n );\n if (\n existing === null ||\n existing.trim().length === 0 ||\n existing.startsWith(GENERATED_SCENARIO_PREFIX)\n ) {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/scenarios/smoke-initial-turn.scenario.ts\",\n INITIAL_SCENARIO_CONTENT,\n );\n }\n}\n\nasync function writeTestingTypes(\n projectRoot: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n if (mode === \"new\") {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/testing-types.ts\",\n REDUCER_TESTING_TYPES_WRAPPER_CONTENT,\n );\n return;\n }\n\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n \"test/testing-types.ts\",\n );\n if (shouldRefreshGeneratedTestingTypes(existing)) {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/testing-types.ts\",\n REDUCER_TESTING_TYPES_WRAPPER_CONTENT,\n );\n }\n}\n\nasync function writeGeneratedTestingStubs(\n projectRoot: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n const header = \"// Generated by dreamboard scaffold. Do not edit by hand.\\n\";\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/base-states.generated.ts\",\n `${header}export const BASE_STATES = {} as const;\\nexport const BASE_STATES_CONTRACT_FINGERPRINT = undefined;\\n`,\n mode,\n );\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/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 mode,\n );\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/testing-contract.ts\",\n `${header}export type BaseId = string;\\nexport type GameView = unknown;\\nexport type InteractionId = string;\\nexport type InteractionParamsOf<_Id extends string> = Record<string, unknown>;\\nexport type PhaseName = string;\\nexport type PlayerId = string;\\nexport type RejectionCode = string;\\nexport type StateName = string;\\nexport type ViewByPhase = Record<string, GameView>;\\nexport type WorkspaceStageName<_Phase extends string = string> = string;\\nexport type Expectation = { [matcher: string]: (...args: unknown[]) => unknown; not: Expectation };\\nexport type ExpectFn = (actual: unknown) => Expectation;\\nexport type InteractionExplanation = { interactionId: string; phase: string; step: string | null; availability: \"available\" | \"notYourTurn\" | \"wrongPhase\" | \"wrongStep\" | \"blocked\"; rules: readonly { ruleId: string; outcome: \"passed\" | \"failed\" | \"notEvaluated\"; errorCode?: string; message?: string; }[]; actor: { required: readonly string[]; playerIsActor: boolean }; inputs: readonly { key: string; kind: string; eligibleCount: number | \"lazy\"; }[]; };\\nexport interface InteractionDescriptorFor<Id extends string = string> { interactionId: Id; [key: string]: unknown; }\\nexport interface ScenarioGameApi { start(): Promise<void>; submit<Id extends InteractionId>(playerId: PlayerId, interactionId: Id, params?: InteractionParamsOf<Id>): Promise<void>; }\\nexport interface BaseContext { game: ScenarioGameApi; players(): readonly PlayerId[]; seat(index: number): PlayerId; }\\nexport interface SharedScenarioContext { game: ScenarioGameApi; players(): readonly PlayerId[]; seat(index: number): PlayerId; state(): StateName; view(playerId: PlayerId): GameView; interactions(playerId: PlayerId): readonly InteractionDescriptorFor[]; explain(playerId: PlayerId, interactionId: InteractionId): InteractionExplanation; expect: ExpectFn; }\\nexport type ScenarioContext<Phase extends PhaseName | undefined = undefined> = Omit<SharedScenarioContext, \"state\" | \"view\"> & { state(): Phase extends PhaseName ? Phase : StateName; view(playerId: PlayerId): Phase extends PhaseName ? ViewByPhase[Phase] : GameView; };\\nexport type ScenarioThenContext<Phase extends PhaseName | undefined = undefined> = ScenarioContext<Phase>;\\nexport interface BaseDefinition { id: string; seed?: number; players?: number; setupProfileId?: string; extends?: BaseId | string; setup: (ctx: BaseContext) => void | Promise<void>; }\\nexport interface ScenarioDefinition<Phase extends PhaseName | undefined = undefined> { id: string; description?: string; from: BaseId | string; phase?: Phase; stage?: Phase extends PhaseName ? WorkspaceStageName<Phase> : never; when: (ctx: ScenarioContext<Phase>) => void | Promise<void>; then: (ctx: ScenarioThenContext<Phase>) => void | Promise<void>; }\\n`,\n mode,\n );\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/scenario-manifest.generated.ts\",\n `${header}export const SCENARIO_MANIFEST = [] as const;\\n`,\n mode,\n );\n}\n\nasync function writeGeneratedTestingStubFile(\n projectRoot: string,\n projectPath: string,\n content: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n if (mode === \"new\") {\n await writeWorkspaceTextFile(projectRoot, projectPath, content);\n return;\n }\n\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n projectPath,\n );\n if (\n existing === null ||\n existing.trim().length === 0 ||\n existing.startsWith(GENERATED_SCENARIO_PREFIX)\n ) {\n await writeWorkspaceTextFile(projectRoot, projectPath, content);\n }\n}\n\nasync function writeTestTsconfig(projectRoot: string): Promise<void> {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/tsconfig.json\",\n `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n noEmit: true,\n },\n include: [\n \"./**/*.ts\",\n \"./**/*.d.ts\",\n \"../shared/**/*.ts\",\n \"../shared/**/*.d.ts\",\n ],\n },\n null,\n 2,\n )}\\n`,\n );\n}\n\nasync function writeManifestTypecheckTsconfig(\n projectRoot: string,\n): Promise<void> {\n await writeWorkspaceTextFile(\n projectRoot,\n MANIFEST_TYPECHECK_CONFIG_FILE,\n `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n noEmit: true,\n allowImportingTsExtensions: true,\n },\n include: [\"./manifest.ts\"],\n },\n null,\n 2,\n )}\\n`,\n );\n}\n\nexport async function migrateLegacyScenarioImports(\n projectRoot: string,\n): Promise<void> {\n if (!(await workspacePathExists(projectRoot, \"test/scenarios\"))) return;\n\n const scenariosRoot = resolveWorkspacePath(projectRoot, \"test/scenarios\");\n const scenarioFiles = await collectScenarioFiles(scenariosRoot);\n for (const filePath of scenarioFiles) {\n const projectPath = toWorkspaceProjectPath(projectRoot, filePath);\n const content = await readWorkspaceTextFile(projectRoot, projectPath);\n if (!content.includes(\"@dreamboard/cli/testing\")) continue;\n\n const relativeToTestingTypes = normalizeImportPath(\n path.relative(\n path.dirname(filePath),\n path.join(projectRoot, \"test\", \"testing-types\"),\n ),\n );\n\n const migrated = content\n .replaceAll('\"@dreamboard/cli/testing\"', `\"${relativeToTestingTypes}\"`)\n .replaceAll(\"'@dreamboard/cli/testing'\", `'${relativeToTestingTypes}'`);\n\n if (migrated !== content) {\n await writeWorkspaceTextFile(projectRoot, projectPath, migrated);\n }\n }\n}\n\nfunction shouldRefreshGeneratedTestingTypes(\n existingContent: string | null,\n): boolean {\n if (existingContent === null || existingContent.trim().length === 0) {\n return true;\n }\n if (existingContent === TESTING_TYPES_STUB) {\n return true;\n }\n return existingContent.startsWith(GENERATED_TESTING_TYPES_PREFIX);\n}\n\nasync function inferInitialTestPlayerCount(\n projectRoot: string,\n): Promise<number> {\n if (!(await workspacePathExists(projectRoot, \"manifest.ts\"))) {\n return 4;\n }\n\n try {\n const manifest = await materializeManifest(projectRoot);\n return manifest.players.optimalPlayers ?? manifest.players.minPlayers ?? 4;\n } catch {\n return 4;\n }\n}\n\nasync function collectScenarioFiles(rootDir: string): Promise<string[]> {\n const files: string[] = [];\n const stack = [rootDir];\n\n while (stack.length > 0) {\n const dir = stack.pop();\n if (!dir) continue;\n\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n stack.push(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".ts\")) {\n files.push(fullPath);\n }\n }\n }\n\n return files;\n}\n\nexport function resolveStaticAssetRoot(\n importUrl: string = import.meta.url,\n): string {\n const candidates = [\n fileURLToPath(new URL(\"../../scaffold/assets/static/\", importUrl)),\n fileURLToPath(new URL(\"./scaffold/assets/static/\", importUrl)),\n fileURLToPath(new URL(\"../scaffold/assets/static/\", importUrl)),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n `Unable to locate CLI static scaffold assets. Checked: ${candidates.join(\", \")}`,\n );\n}\n\nasync function getStaticAssetEntries(): Promise<StaticAssetEntry[]> {\n const files = await walkFiles(STATIC_ASSET_ROOT);\n const entries: StaticAssetEntry[] = [];\n\n for (const filePath of files) {\n const targetPath = normalizeOwnedProjectPath(\n path.relative(STATIC_ASSET_ROOT, filePath).replaceAll(path.sep, \"/\"),\n );\n if (targetPath === null) {\n throw new Error(`Unsafe static scaffold asset path: ${filePath}`);\n }\n entries.push({\n targetPath,\n content: await readFile(filePath, \"utf8\"),\n });\n }\n\n entries.sort((left, right) =>\n left.targetPath.localeCompare(right.targetPath),\n );\n return entries;\n}\n\nasync function getDynamicStaticEntries(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions = {},\n): Promise<StaticAssetEntry[]> {\n const entries: StaticAssetEntry[] = [\n {\n targetPath: \"package.json\",\n content: await buildRootPackageJson(projectRoot, mode, options),\n },\n {\n targetPath: \"ui/package.json\",\n content: buildUiPackageJson(),\n },\n ];\n\n if (options.localMaintainerRegistry) {\n entries.push({\n targetPath: \".npmrc\",\n content: buildWorkspaceNpmrc(options.localMaintainerRegistry.registryUrl),\n });\n }\n\n return entries;\n}\n\nasync function getExpectedStaticEntries(\n projectRoot: string,\n): Promise<StaticAssetEntry[]> {\n const entries = [\n ...(await getStaticAssetEntries()).filter(\n (entry) => entry.targetPath !== \".npmrc\",\n ),\n ...(await getDynamicStaticEntries(projectRoot, \"update\")),\n ];\n entries.sort((left, right) =>\n left.targetPath.localeCompare(right.targetPath),\n );\n return entries;\n}\n\nasync function walkFiles(rootDir: string): Promise<string[]> {\n const files: string[] = [];\n const stack = [rootDir];\n\n while (stack.length > 0) {\n const currentDir = stack.pop();\n if (!currentDir) continue;\n\n const entries = await readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(currentDir, entry.name);\n if (entry.isDirectory()) {\n stack.push(fullPath);\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n }\n\n files.sort((left, right) => left.localeCompare(right));\n return files;\n}\n\nasync function buildRootPackageJson(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions,\n): Promise<string> {\n const sdkPackageRanges = {\n ...SDK_DEPENDENCY_RANGES,\n ...(options.localMaintainerRegistry?.packages ?? {}),\n };\n const existingPackageJson =\n mode === \"update\" &&\n (await workspacePathExists(projectRoot, \"package.json\"))\n ? (JSON.parse(\n await readWorkspaceTextFile(projectRoot, \"package.json\"),\n ) as RootPackageJsonShape)\n : null;\n const {\n dreamboardFrameworkVersion: _legacyFrameworkVersion,\n ...existingPackageJsonWithoutLegacyVersion\n } = existingPackageJson ?? {};\n const frameworkDependencies = {\n \"@dreamboard-games/sdk\":\n sdkPackageRanges[\"@dreamboard-games/sdk\"] ??\n SDK_DEPENDENCY_RANGES[\"@dreamboard-games/sdk\"],\n ...SHARED_DEPENDENCIES,\n ...ROOT_APP_DEPENDENCIES,\n };\n const frameworkDevDependencies = {\n ...SHARED_DEV_DEPENDENCIES,\n ...DEV_HOST_DEPENDENCY_RANGES,\n };\n const nextPackageJson: RootPackageJsonShape = {\n ...existingPackageJsonWithoutLegacyVersion,\n private: true,\n packageManager: AUTHORING_RELEASE_SET.packageManager,\n scripts: {\n ...(existingPackageJson?.scripts ?? {}),\n ...FRAMEWORK_SCRIPTS,\n },\n dependencies: {\n ...(existingPackageJson?.dependencies ?? {}),\n ...frameworkDependencies,\n },\n devDependencies: {\n ...(existingPackageJson?.devDependencies ?? {}),\n ...frameworkDevDependencies,\n },\n pnpm: mergePnpmConfig(existingPackageJson?.pnpm),\n };\n return `${JSON.stringify(nextPackageJson, null, 2)}\\n`;\n}\n\nfunction mergePnpmConfig(\n existingPnpm: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const existingOverrides =\n existingPnpm?.overrides &&\n typeof existingPnpm.overrides === \"object\" &&\n !Array.isArray(existingPnpm.overrides)\n ? (existingPnpm.overrides as Record<string, unknown>)\n : {};\n return {\n ...(existingPnpm ?? {}),\n overrides: {\n ...existingOverrides,\n ...FRAMEWORK_PNPM_OVERRIDES,\n ...DREAMBOARD_PACKAGE_OVERRIDES,\n },\n };\n}\n\nfunction buildWorkspaceNpmrc(registryUrl: string): string {\n return `@dreamboard-games:registry=${registryUrl}\\n`;\n}\n\nfunction buildUiPackageJson(): string {\n return `${JSON.stringify(\n {\n private: true,\n dependencies: SHARED_DEPENDENCIES,\n devDependencies: SHARED_DEV_DEPENDENCIES,\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction normalizeImportPath(relativePath: string): string {\n const normalized = relativePath.replaceAll(\"\\\\\", \"/\");\n if (normalized.startsWith(\".\")) return normalized;\n return `./${normalized}`;\n}\n\nfunction toWorkspaceProjectPath(projectRoot: string, filePath: string): string {\n const relativePath = path\n .relative(path.resolve(projectRoot), path.resolve(filePath))\n .replaceAll(path.sep, \"/\");\n const projectPath = normalizeOwnedProjectPath(relativePath);\n if (projectPath === null) {\n throw new Error(`Unsafe project path: ${relativePath}`);\n }\n return projectPath;\n}\n\nfunction summarizePaths(paths: readonly string[]): string {\n const maxShown = 5;\n const shown = paths.slice(0, maxShown).join(\", \");\n if (paths.length <= maxShown) return shown;\n return `${shown}, and ${paths.length - maxShown} more`;\n}\n","// Generated by scripts/generate-authoring-release-set.ts. Do not edit by hand.\nimport type { AuthoringReleaseSetV1 } from \"./authoring-release-set.js\";\n\nexport const AUTHORING_RELEASE_SET = {\n \"schemaVersion\": 1,\n \"channel\": \"public\",\n \"packages\": {\n \"cli\": {\n \"name\": \"@dreamboard-games/cli\",\n \"version\": \"0.1.30-alpha.39\"\n },\n \"sdk\": {\n \"name\": \"@dreamboard-games/sdk\",\n \"version\": \"0.4.0-alpha.6\"\n },\n \"apiClient\": {\n \"name\": \"@dreamboard-games/api-client\",\n \"version\": \"0.3.0-alpha.4\"\n },\n \"devHost\": {\n \"name\": \"@dreamboard-games/dev-host\",\n \"version\": \"0.1.30-alpha.26\"\n }\n },\n \"protocols\": {\n \"authoringAdapter\": 1,\n \"devHost\": 1,\n \"verifier\": 1\n },\n \"schemas\": {\n \"scaffold\": 2,\n \"manifest\": 2,\n \"generatedArtifacts\": 1\n },\n \"registry\": {\n \"kind\": \"public-npm\",\n \"portable\": true\n },\n \"packageManager\": \"pnpm@10.4.1\",\n \"releaseSetId\": \"sha256:99293016258deb0093af008665e467ea2bee5f28eb93faa1332441bef9fa62a4\"\n} as const satisfies AuthoringReleaseSetV1;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/services/project/static-scaffold.ts","../../src/release/authoring-release-set.generated.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { readdir, readFile, rmdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { GameTopologyManifest } from \"@dreamboard-games/sdk/types\";\nimport { AUTHORING_RELEASE_SET } from \"../../release/authoring-release-set.js\";\nimport { REDUCER_TESTING_TYPES_WRAPPER_CONTENT } from \"../../templates/testing-types-content.js\";\nimport {\n MANIFEST_TYPECHECK_CONFIG_FILE,\n PROJECT_CONFIG_FILE,\n PROJECT_DIR_NAME,\n} from \"../../constants.js\";\nimport type { LocalMaintainerRegistryConfig } from \"../../types.js\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport { materializeManifest } from \"./manifest-authoring.js\";\nimport { isDynamicSeedPath } from \"./scaffold-ownership.js\";\nimport {\n normalizeOwnedProjectPath,\n readWorkspaceTextFile,\n readWorkspaceTextFileIfExists,\n removeWorkspacePath,\n resolveWorkspacePath,\n unlinkWorkspaceFile,\n workspacePathExists,\n writeWorkspaceTextFile,\n} from \"./workspace-path.js\";\nimport {\n FRAMEWORK_PNPM_OVERRIDES,\n FRAMEWORK_REACT_DEPENDENCIES,\n FRAMEWORK_ZOD_VERSION,\n} from \"./framework-dependencies.js\";\n\ntype StaticScaffoldMode = \"new\" | \"update\";\ntype StaticAssetEntry = {\n targetPath: string;\n content: string;\n};\ntype StaticScaffoldOptions = {\n localMaintainerRegistry?: LocalMaintainerRegistryConfig | null;\n};\ntype RootPackageJsonShape = {\n private?: boolean;\n packageManager?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n overrides?: Record<string, unknown>;\n pnpm?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\nconst DREAMBOARD_SCAFFOLD_REFRESH_COMMAND =\n \"dreamboard project create or dreamboard project clone\";\nconst DREAMBOARD_GITIGNORE_BLOCK = [\n \"# Dreamboard local state\",\n \".dreamboard/state.json\",\n \".dreamboard/snapshot.json\",\n \".dreamboard/dev/\",\n \".dreamboard/generated/\",\n \"node_modules/\",\n \"ui/node_modules/\",\n \"\",\n].join(\"\\n\");\nconst TESTING_TYPES_STUB =\n \"export function defineScenario(scenario) { return scenario; }\\n\";\nconst GENERATED_TESTING_TYPES_PREFIX = \"// Generated by dreamboard\";\nconst GENERATED_SCENARIO_PREFIX = \"// Generated by dreamboard scaffold.\";\nconst LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT = `export {\n ErrorBoundary,\n type ErrorBoundaryProps,\n} from \"@dreamboard-games/sdk/ui\";\nexport { PluginRuntime, type PluginRuntimeProps } from \"@dreamboard-games/sdk/runtime\";\n`;\nconst OLD_LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT = [\n \"export {\",\n \" ErrorBoundary,\",\n \" PluginRuntime,\",\n \" type ErrorBoundaryProps,\",\n \" type PluginRuntimeProps,\",\n `} from \"@dreamboard/ui-${\"sdk\"}\";`,\n \"\",\n].join(\"\\n\");\nconst OLD_PUBLIC_DREAMBOARD_COMPONENT_INDEX_CONTENT = [\n \"export {\",\n \" ErrorBoundary,\",\n \" PluginRuntime,\",\n \" type ErrorBoundaryProps,\",\n \" type PluginRuntimeProps,\",\n `} from \"@dreamboard-games/ui-${\"sdk\"}\";`,\n \"\",\n].join(\"\\n\");\nconst INITIAL_SCENARIO_CONTENT = `${GENERATED_SCENARIO_PREFIX}\nimport { defineScenario } from \"../testing-types\";\n\nexport default defineScenario({\n id: \"smoke-initial-turn\",\n description:\n \"Sanity check that the scaffolded workspace boots into its initial phase.\",\n from: \"initial-turn\",\n when: async () => undefined,\n then: ({ expect, players, state }) => {\n const playerIds = players();\n expect(playerIds).toHaveLength(playerIds.length);\n expect(playerIds.length).toBeGreaterThanOrEqual(1);\n expect(state()).toBe(\"setup\");\n },\n});\n`;\nconst STATIC_ASSET_ROOT = resolveStaticAssetRoot();\nconst SDK_DEPENDENCY_RANGES = {\n \"@dreamboard-games/sdk\": AUTHORING_RELEASE_SET.packages.sdk.version,\n} as const;\nconst DEV_HOST_DEPENDENCY_RANGES = {\n \"@dreamboard-games/dev-host\": AUTHORING_RELEASE_SET.packages.devHost.version,\n} as const;\nconst DREAMBOARD_PACKAGE_OVERRIDES = {\n \"@dreamboard-games/api-client\":\n AUTHORING_RELEASE_SET.packages.apiClient.version,\n \"@dreamboard-games/dev-host\": AUTHORING_RELEASE_SET.packages.devHost.version,\n \"@dreamboard-games/sdk\": AUTHORING_RELEASE_SET.packages.sdk.version,\n} as const;\n\nconst FRAMEWORK_SCRIPTS = {\n dev: \"dreamboard dev\",\n \"test:ui\":\n \"tsx --tsconfig test/tsconfig.tsx-runtime.json --test test/ui/**/*.test.tsx\",\n typecheck: `tsc --noEmit -p ${MANIFEST_TYPECHECK_CONFIG_FILE} && tsc --noEmit -p app/tsconfig.json && tsc --noEmit -p ui/tsconfig.json`,\n \"typecheck:manifest\": `tsc --noEmit -p ${MANIFEST_TYPECHECK_CONFIG_FILE}`,\n \"typecheck:app\": \"tsc --noEmit -p app/tsconfig.json\",\n \"typecheck:ui\": \"tsc --noEmit -p ui/tsconfig.json\",\n} as const;\nconst SHARED_DEPENDENCIES = {\n ...FRAMEWORK_REACT_DEPENDENCIES,\n} as const;\nconst ROOT_APP_DEPENDENCIES = {\n zod: FRAMEWORK_ZOD_VERSION,\n} as const;\nconst SHARED_DEV_DEPENDENCIES = {\n typescript: \"^5.9.2\",\n \"@types/node\": \"^24.5.2\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n csstype: \"^3.1.3\",\n tsx: \"^4.20.5\",\n} as const;\n\nexport async function scaffoldStaticWorkspace(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions = {},\n): Promise<void> {\n await writeFrameworkStaticFiles(projectRoot, mode, options);\n await ensureDreamboardGitignore(projectRoot);\n await writeManifestTypecheckTsconfig(projectRoot);\n await removeLegacyVendoredSdkPaths(projectRoot);\n await removeLegacyDreamboardComponentPath(projectRoot);\n\n await ensureDir(resolveWorkspacePath(projectRoot, \"test/bases\"));\n await ensureDir(resolveWorkspacePath(projectRoot, \"test/scenarios\"));\n await ensureDir(resolveWorkspacePath(projectRoot, \"test/generated\"));\n\n await writeTestReadme(projectRoot);\n await writeGeneratedTestingStubs(projectRoot, mode);\n const initialTestPlayerCount = await inferInitialTestPlayerCount(projectRoot);\n await writeInitialBase(projectRoot, mode, initialTestPlayerCount);\n await writeInitialScenario(projectRoot, mode);\n await writeTestingTypes(projectRoot, mode);\n await writeTestTsconfig(projectRoot);\n\n if (await workspacePathExists(projectRoot, \"test/testing-types.d.ts\")) {\n await unlinkWorkspaceFile(projectRoot, \"test/testing-types.d.ts\");\n }\n if (await workspacePathExists(projectRoot, \"test/base-scenarios.json\")) {\n await unlinkWorkspaceFile(projectRoot, \"test/base-scenarios.json\");\n }\n\n await migrateLegacyScenarioImports(projectRoot);\n}\n\nasync function ensureDreamboardGitignore(projectRoot: string): Promise<void> {\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n \".gitignore\",\n );\n if (existing?.includes(\".dreamboard/state.json\")) {\n return;\n }\n await writeWorkspaceTextFile(\n projectRoot,\n \".gitignore\",\n `${existing ? `${existing.trimEnd()}\\n\\n` : \"\"}${DREAMBOARD_GITIGNORE_BLOCK}`,\n );\n}\n\nexport async function assertCliStaticScaffoldComplete(\n projectRoot: string,\n deletedPaths: readonly string[] = [],\n): Promise<void> {\n const expectedEntries = await getExpectedStaticEntries(projectRoot);\n const missingOrBlankPaths: string[] = [];\n\n for (const entry of expectedEntries) {\n const content = await readWorkspaceTextFileIfExists(\n projectRoot,\n entry.targetPath,\n );\n\n if (content === null || content.trim().length === 0) {\n missingOrBlankPaths.push(entry.targetPath);\n }\n }\n\n const staticPaths = new Set(expectedEntries.map((entry) => entry.targetPath));\n const deletedStaticPaths = deletedPaths\n .map(normalizeOwnedProjectPath)\n .filter(\n (filePath): filePath is string =>\n filePath !== null && staticPaths.has(filePath),\n )\n .sort();\n\n if (missingOrBlankPaths.length === 0 && deletedStaticPaths.length === 0) {\n return;\n }\n\n const problems: string[] = [];\n if (missingOrBlankPaths.length > 0) {\n problems.push(\n `missing or blank: ${summarizePaths(missingOrBlankPaths.sort())}`,\n );\n }\n if (deletedStaticPaths.length > 0) {\n problems.push(`deleted: ${summarizePaths(deletedStaticPaths)}`);\n }\n\n throw new Error(\n `CLI static scaffold is incomplete (${problems.join(\"; \")}). Refresh the project scaffold with ${DREAMBOARD_SCAFFOLD_REFRESH_COMMAND} before building or testing.`,\n );\n}\n\nasync function writeFrameworkStaticFiles(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions,\n): Promise<void> {\n const assetEntries = await getStaticAssetEntries();\n\n for (const entry of assetEntries) {\n // Dynamic seed files are user-customizable: only write them on first\n // scaffold; preserve existing content on subsequent updates.\n if (mode === \"update\" && isDynamicSeedPath(entry.targetPath)) {\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n entry.targetPath,\n );\n if (existing !== null && existing.trim().length > 0) {\n continue;\n }\n }\n await writeWorkspaceTextFile(projectRoot, entry.targetPath, entry.content);\n }\n\n for (const entry of await getDynamicStaticEntries(\n projectRoot,\n mode,\n options,\n )) {\n await writeWorkspaceTextFile(projectRoot, entry.targetPath, entry.content);\n }\n\n if (!options.localMaintainerRegistry) {\n await removeWorkspacePath(projectRoot, \".npmrc\", { force: true });\n }\n}\n\nasync function removeLegacyVendoredSdkPaths(\n projectRoot: string,\n): Promise<void> {\n await removeWorkspacePath(projectRoot, \"app/sdk\", {\n recursive: true,\n force: true,\n });\n await removeWorkspacePath(projectRoot, \"ui/sdk\", {\n recursive: true,\n force: true,\n });\n}\n\nasync function removeLegacyDreamboardComponentPath(\n projectRoot: string,\n): Promise<void> {\n const legacyIndexProjectPath = \"ui/components/dreamboard/index.ts\";\n const legacyDirPath = resolveWorkspacePath(\n projectRoot,\n \"ui/components/dreamboard\",\n );\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n legacyIndexProjectPath,\n );\n\n const removableLegacyContents = new Set([\n LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT.trim(),\n OLD_LEGACY_DREAMBOARD_COMPONENT_INDEX_CONTENT.trim(),\n OLD_PUBLIC_DREAMBOARD_COMPONENT_INDEX_CONTENT.trim(),\n ]);\n\n if (existing === null || !removableLegacyContents.has(existing.trim())) {\n return;\n }\n\n await unlinkWorkspaceFile(projectRoot, legacyIndexProjectPath);\n const remainingEntries = await readdir(legacyDirPath).catch(() => []);\n if (remainingEntries.length === 0) {\n await rmdir(legacyDirPath);\n }\n}\n\nasync function writeTestReadme(projectRoot: string): Promise<void> {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/README.md\",\n \"# Dreamboard Test Workspace\\n\\nTypeScript bases live in `test/bases/*.base.ts` and scenarios live in `test/scenarios/*.scenario.ts`.\\n\\n1. Define reusable seeded bases with `defineBase({ id, seed, players, setupProfileId?, setup })`.\\n2. Define scenarios with `defineScenario({ id, from, when, then })`.\\n3. Scenario assertions can read `players()`, `state()`, `view(playerId)`, and `interactions(playerId)`.\\n4. Run deterministic scenario tests: `dreamboard test`.\\n5. Run a single scenario when needed: `dreamboard test --scenario <scenario-id>`.\\n\\nImport test helpers from `../testing-types`.\\n\\nGenerated artifacts are written to `test/generated/*` and should not be edited manually.\\n\",\n );\n}\n\nasync function writeInitialBase(\n projectRoot: string,\n mode: StaticScaffoldMode,\n players: number,\n): Promise<void> {\n if (mode === \"update\") {\n return;\n }\n\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/bases/initial-turn.base.ts\",\n `import { defineBase } from \"../testing-types\";\n\nexport default defineBase({\n id: \"initial-turn\",\n seed: 1337,\n players: ${players},\n setup: async () => undefined,\n});\n`,\n );\n}\n\nasync function writeInitialScenario(\n projectRoot: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n if (mode === \"new\") {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/scenarios/smoke-initial-turn.scenario.ts\",\n INITIAL_SCENARIO_CONTENT,\n );\n return;\n }\n\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n \"test/scenarios/smoke-initial-turn.scenario.ts\",\n );\n if (\n existing === null ||\n existing.trim().length === 0 ||\n existing.startsWith(GENERATED_SCENARIO_PREFIX)\n ) {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/scenarios/smoke-initial-turn.scenario.ts\",\n INITIAL_SCENARIO_CONTENT,\n );\n }\n}\n\nasync function writeTestingTypes(\n projectRoot: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n if (mode === \"new\") {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/testing-types.ts\",\n REDUCER_TESTING_TYPES_WRAPPER_CONTENT,\n );\n return;\n }\n\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n \"test/testing-types.ts\",\n );\n if (shouldRefreshGeneratedTestingTypes(existing)) {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/testing-types.ts\",\n REDUCER_TESTING_TYPES_WRAPPER_CONTENT,\n );\n }\n}\n\nasync function writeGeneratedTestingStubs(\n projectRoot: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n const header = \"// Generated by dreamboard scaffold. Do not edit by hand.\\n\";\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/base-states.generated.ts\",\n `${header}export const BASE_STATES = {} as const;\\nexport const BASE_STATES_CONTRACT_FINGERPRINT = undefined;\\n`,\n mode,\n );\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/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 mode,\n );\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/testing-contract.ts\",\n `${header}export type BaseId = string;\\nexport type GameView = unknown;\\nexport type InteractionId = string;\\nexport type InteractionParamsOf<_Id extends string> = Record<string, unknown>;\\nexport type PhaseName = string;\\nexport type PlayerId = string;\\nexport type RejectionCode = string;\\nexport type StateName = string;\\nexport type ViewByPhase = Record<string, GameView>;\\nexport type WorkspaceStageName<_Phase extends string = string> = string;\\nexport type Expectation = { [matcher: string]: (...args: unknown[]) => unknown; not: Expectation };\\nexport type ExpectFn = (actual: unknown) => Expectation;\\nexport type InteractionExplanation = { interactionId: string; phase: string; step: string | null; availability: \"available\" | \"notYourTurn\" | \"wrongPhase\" | \"wrongStep\" | \"blocked\"; rules: readonly { ruleId: string; outcome: \"passed\" | \"failed\" | \"notEvaluated\"; errorCode?: string; message?: string; }[]; actor: { required: readonly string[]; playerIsActor: boolean }; inputs: readonly { key: string; kind: string; eligibleCount: number | \"lazy\"; }[]; };\\nexport interface InteractionDescriptorFor<Id extends string = string> { interactionId: Id; [key: string]: unknown; }\\nexport interface ScenarioGameApi { start(): Promise<void>; submit<Id extends InteractionId>(playerId: PlayerId, interactionId: Id, params?: InteractionParamsOf<Id>): Promise<void>; }\\nexport interface BaseContext { game: ScenarioGameApi; players(): readonly PlayerId[]; seat(index: number): PlayerId; }\\nexport interface SharedScenarioContext { game: ScenarioGameApi; players(): readonly PlayerId[]; seat(index: number): PlayerId; state(): StateName; view(playerId: PlayerId): GameView; interactions(playerId: PlayerId): readonly InteractionDescriptorFor[]; explain(playerId: PlayerId, interactionId: InteractionId): InteractionExplanation; expect: ExpectFn; }\\nexport type ScenarioContext<Phase extends PhaseName | undefined = undefined> = Omit<SharedScenarioContext, \"state\" | \"view\"> & { state(): Phase extends PhaseName ? Phase : StateName; view(playerId: PlayerId): Phase extends PhaseName ? ViewByPhase[Phase] : GameView; };\\nexport type ScenarioThenContext<Phase extends PhaseName | undefined = undefined> = ScenarioContext<Phase>;\\nexport interface BaseDefinition { id: string; seed?: number; players?: number; setupProfileId?: string; extends?: BaseId | string; setup: (ctx: BaseContext) => void | Promise<void>; }\\nexport interface ScenarioDefinition<Phase extends PhaseName | undefined = undefined> { id: string; description?: string; from: BaseId | string; phase?: Phase; stage?: Phase extends PhaseName ? WorkspaceStageName<Phase> : never; when: (ctx: ScenarioContext<Phase>) => void | Promise<void>; then: (ctx: ScenarioThenContext<Phase>) => void | Promise<void>; }\\n`,\n mode,\n );\n await writeGeneratedTestingStubFile(\n projectRoot,\n \"test/generated/scenario-manifest.generated.ts\",\n `${header}export const SCENARIO_MANIFEST = [] as const;\\n`,\n mode,\n );\n}\n\nasync function writeGeneratedTestingStubFile(\n projectRoot: string,\n projectPath: string,\n content: string,\n mode: StaticScaffoldMode,\n): Promise<void> {\n if (mode === \"new\") {\n await writeWorkspaceTextFile(projectRoot, projectPath, content);\n return;\n }\n\n const existing = await readWorkspaceTextFileIfExists(\n projectRoot,\n projectPath,\n );\n if (\n existing === null ||\n existing.trim().length === 0 ||\n existing.startsWith(GENERATED_SCENARIO_PREFIX)\n ) {\n await writeWorkspaceTextFile(projectRoot, projectPath, content);\n }\n}\n\nasync function writeTestTsconfig(projectRoot: string): Promise<void> {\n await writeWorkspaceTextFile(\n projectRoot,\n \"test/tsconfig.json\",\n `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n noEmit: true,\n },\n include: [\n \"./**/*.ts\",\n \"./**/*.d.ts\",\n \"../shared/**/*.ts\",\n \"../shared/**/*.d.ts\",\n ],\n },\n null,\n 2,\n )}\\n`,\n );\n}\n\nasync function writeManifestTypecheckTsconfig(\n projectRoot: string,\n): Promise<void> {\n await writeWorkspaceTextFile(\n projectRoot,\n MANIFEST_TYPECHECK_CONFIG_FILE,\n `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n noEmit: true,\n allowImportingTsExtensions: true,\n },\n include: [\"./manifest.ts\"],\n },\n null,\n 2,\n )}\\n`,\n );\n}\n\nexport async function migrateLegacyScenarioImports(\n projectRoot: string,\n): Promise<void> {\n if (!(await workspacePathExists(projectRoot, \"test/scenarios\"))) return;\n\n const scenariosRoot = resolveWorkspacePath(projectRoot, \"test/scenarios\");\n const scenarioFiles = await collectScenarioFiles(scenariosRoot);\n for (const filePath of scenarioFiles) {\n const projectPath = toWorkspaceProjectPath(projectRoot, filePath);\n const content = await readWorkspaceTextFile(projectRoot, projectPath);\n if (!content.includes(\"@dreamboard/cli/testing\")) continue;\n\n const relativeToTestingTypes = normalizeImportPath(\n path.relative(\n path.dirname(filePath),\n path.join(projectRoot, \"test\", \"testing-types\"),\n ),\n );\n\n const migrated = content\n .replaceAll('\"@dreamboard/cli/testing\"', `\"${relativeToTestingTypes}\"`)\n .replaceAll(\"'@dreamboard/cli/testing'\", `'${relativeToTestingTypes}'`);\n\n if (migrated !== content) {\n await writeWorkspaceTextFile(projectRoot, projectPath, migrated);\n }\n }\n}\n\nfunction shouldRefreshGeneratedTestingTypes(\n existingContent: string | null,\n): boolean {\n if (existingContent === null || existingContent.trim().length === 0) {\n return true;\n }\n if (existingContent === TESTING_TYPES_STUB) {\n return true;\n }\n return existingContent.startsWith(GENERATED_TESTING_TYPES_PREFIX);\n}\n\nasync function inferInitialTestPlayerCount(\n projectRoot: string,\n): Promise<number> {\n if (!(await workspacePathExists(projectRoot, \"manifest.ts\"))) {\n return 4;\n }\n\n try {\n const manifest = await materializeManifest(projectRoot);\n return manifest.players.optimalPlayers ?? manifest.players.minPlayers ?? 4;\n } catch {\n return 4;\n }\n}\n\nasync function collectScenarioFiles(rootDir: string): Promise<string[]> {\n const files: string[] = [];\n const stack = [rootDir];\n\n while (stack.length > 0) {\n const dir = stack.pop();\n if (!dir) continue;\n\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n stack.push(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".ts\")) {\n files.push(fullPath);\n }\n }\n }\n\n return files;\n}\n\nexport function resolveStaticAssetRoot(\n importUrl: string = import.meta.url,\n): string {\n const candidates = [\n fileURLToPath(new URL(\"../../scaffold/assets/static/\", importUrl)),\n fileURLToPath(new URL(\"./scaffold/assets/static/\", importUrl)),\n fileURLToPath(new URL(\"../scaffold/assets/static/\", importUrl)),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n `Unable to locate CLI static scaffold assets. Checked: ${candidates.join(\", \")}`,\n );\n}\n\nasync function getStaticAssetEntries(): Promise<StaticAssetEntry[]> {\n const files = await walkFiles(STATIC_ASSET_ROOT);\n const entries: StaticAssetEntry[] = [];\n\n for (const filePath of files) {\n const targetPath = normalizeOwnedProjectPath(\n path.relative(STATIC_ASSET_ROOT, filePath).replaceAll(path.sep, \"/\"),\n );\n if (targetPath === null) {\n throw new Error(`Unsafe static scaffold asset path: ${filePath}`);\n }\n entries.push({\n targetPath,\n content: await readFile(filePath, \"utf8\"),\n });\n }\n\n entries.sort((left, right) =>\n left.targetPath.localeCompare(right.targetPath),\n );\n return entries;\n}\n\nasync function getDynamicStaticEntries(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions = {},\n): Promise<StaticAssetEntry[]> {\n const entries: StaticAssetEntry[] = [\n {\n targetPath: \"package.json\",\n content: await buildRootPackageJson(projectRoot, mode, options),\n },\n {\n targetPath: \"ui/package.json\",\n content: buildUiPackageJson(),\n },\n ];\n\n if (options.localMaintainerRegistry) {\n entries.push({\n targetPath: \".npmrc\",\n content: buildWorkspaceNpmrc(options.localMaintainerRegistry.registryUrl),\n });\n }\n\n return entries;\n}\n\nasync function getExpectedStaticEntries(\n projectRoot: string,\n): Promise<StaticAssetEntry[]> {\n const entries = [\n ...(await getStaticAssetEntries()).filter(\n (entry) => entry.targetPath !== \".npmrc\",\n ),\n ...(await getDynamicStaticEntries(projectRoot, \"update\")),\n ];\n entries.sort((left, right) =>\n left.targetPath.localeCompare(right.targetPath),\n );\n return entries;\n}\n\nasync function walkFiles(rootDir: string): Promise<string[]> {\n const files: string[] = [];\n const stack = [rootDir];\n\n while (stack.length > 0) {\n const currentDir = stack.pop();\n if (!currentDir) continue;\n\n const entries = await readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(currentDir, entry.name);\n if (entry.isDirectory()) {\n stack.push(fullPath);\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n }\n\n files.sort((left, right) => left.localeCompare(right));\n return files;\n}\n\nasync function buildRootPackageJson(\n projectRoot: string,\n mode: StaticScaffoldMode,\n options: StaticScaffoldOptions,\n): Promise<string> {\n const sdkPackageRanges = {\n ...SDK_DEPENDENCY_RANGES,\n ...(options.localMaintainerRegistry?.packages ?? {}),\n };\n const existingPackageJson =\n mode === \"update\" &&\n (await workspacePathExists(projectRoot, \"package.json\"))\n ? (JSON.parse(\n await readWorkspaceTextFile(projectRoot, \"package.json\"),\n ) as RootPackageJsonShape)\n : null;\n const {\n dreamboardFrameworkVersion: _legacyFrameworkVersion,\n ...existingPackageJsonWithoutLegacyVersion\n } = existingPackageJson ?? {};\n const frameworkDependencies = {\n \"@dreamboard-games/sdk\":\n sdkPackageRanges[\"@dreamboard-games/sdk\"] ??\n SDK_DEPENDENCY_RANGES[\"@dreamboard-games/sdk\"],\n ...SHARED_DEPENDENCIES,\n ...ROOT_APP_DEPENDENCIES,\n };\n const frameworkDevDependencies = {\n ...SHARED_DEV_DEPENDENCIES,\n ...DEV_HOST_DEPENDENCY_RANGES,\n };\n const nextPackageJson: RootPackageJsonShape = {\n ...existingPackageJsonWithoutLegacyVersion,\n private: true,\n packageManager: AUTHORING_RELEASE_SET.packageManager,\n scripts: {\n ...(existingPackageJson?.scripts ?? {}),\n ...FRAMEWORK_SCRIPTS,\n },\n dependencies: {\n ...(existingPackageJson?.dependencies ?? {}),\n ...frameworkDependencies,\n },\n devDependencies: {\n ...(existingPackageJson?.devDependencies ?? {}),\n ...frameworkDevDependencies,\n },\n pnpm: mergePnpmConfig(existingPackageJson?.pnpm),\n };\n return `${JSON.stringify(nextPackageJson, null, 2)}\\n`;\n}\n\nfunction mergePnpmConfig(\n existingPnpm: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const existingOverrides =\n existingPnpm?.overrides &&\n typeof existingPnpm.overrides === \"object\" &&\n !Array.isArray(existingPnpm.overrides)\n ? (existingPnpm.overrides as Record<string, unknown>)\n : {};\n return {\n ...(existingPnpm ?? {}),\n overrides: {\n ...existingOverrides,\n ...FRAMEWORK_PNPM_OVERRIDES,\n ...DREAMBOARD_PACKAGE_OVERRIDES,\n },\n };\n}\n\nfunction buildWorkspaceNpmrc(registryUrl: string): string {\n return `@dreamboard-games:registry=${registryUrl}\\n`;\n}\n\nfunction buildUiPackageJson(): string {\n return `${JSON.stringify(\n {\n private: true,\n dependencies: SHARED_DEPENDENCIES,\n devDependencies: SHARED_DEV_DEPENDENCIES,\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction normalizeImportPath(relativePath: string): string {\n const normalized = relativePath.replaceAll(\"\\\\\", \"/\");\n if (normalized.startsWith(\".\")) return normalized;\n return `./${normalized}`;\n}\n\nfunction toWorkspaceProjectPath(projectRoot: string, filePath: string): string {\n const relativePath = path\n .relative(path.resolve(projectRoot), path.resolve(filePath))\n .replaceAll(path.sep, \"/\");\n const projectPath = normalizeOwnedProjectPath(relativePath);\n if (projectPath === null) {\n throw new Error(`Unsafe project path: ${relativePath}`);\n }\n return projectPath;\n}\n\nfunction summarizePaths(paths: readonly string[]): string {\n const maxShown = 5;\n const shown = paths.slice(0, maxShown).join(\", \");\n if (paths.length <= maxShown) return shown;\n return `${shown}, and ${paths.length - maxShown} more`;\n}\n","// Generated by scripts/generate-authoring-release-set.ts. Do not edit by hand.\nimport type { AuthoringReleaseSetV1 } from \"./authoring-release-set.js\";\n\nexport const AUTHORING_RELEASE_SET = {\n \"schemaVersion\": 1,\n \"channel\": \"public\",\n \"packages\": {\n \"cli\": {\n \"name\": \"@dreamboard-games/cli\",\n \"version\": \"0.1.30-alpha.40\"\n },\n \"sdk\": {\n \"name\": \"@dreamboard-games/sdk\",\n \"version\": \"0.4.0-alpha.6\"\n },\n \"apiClient\": {\n \"name\": \"@dreamboard-games/api-client\",\n \"version\": \"0.3.0-alpha.4\"\n },\n \"devHost\": {\n \"name\": \"@dreamboard-games/dev-host\",\n \"version\": \"0.1.30-alpha.27\"\n }\n },\n \"protocols\": {\n \"authoringAdapter\": 1,\n \"devHost\": 1,\n \"verifier\": 1\n },\n \"schemas\": {\n \"scaffold\": 2,\n \"manifest\": 2,\n \"generatedArtifacts\": 1\n },\n \"registry\": {\n \"kind\": \"public-npm\",\n \"portable\": true\n },\n \"packageManager\": \"pnpm@10.4.1\",\n \"releaseSetId\": \"sha256:b1ba68e0bd81fbf6c44d39665e716f5fba81342036f04f1d102b12da77c73f1c\"\n} as const satisfies AuthoringReleaseSetV1;\n"],"mappings":"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","names":[]}
@@ -29,7 +29,6 @@ function normalizeProjectBinding(config) {
29
29
  return {
30
30
  deploymentId: config.deploymentId ?? LEGACY_DEFAULT_DEPLOYMENT_ID,
31
31
  ownerScopeId: config.ownerScopeId ?? LEGACY_DEFAULT_OWNER_SCOPE_ID,
32
- gameId: config.gameId,
33
32
  remoteHeadDigest: config.remoteHeadDigest,
34
33
  jobId: config.jobId,
35
34
  agentManaged: config.agentManaged,
@@ -63,7 +62,6 @@ function mergeManifestAndBinding(manifest, binding, bindingKey) {
63
62
  deploymentId: LEGACY_DEFAULT_DEPLOYMENT_ID,
64
63
  ownerScopeId: LEGACY_DEFAULT_OWNER_SCOPE_ID
65
64
  },
66
- gameId: binding?.gameId ?? manifest.projectId,
67
65
  bindingKey: bindingKey ?? `${binding?.deploymentId ?? LEGACY_DEFAULT_DEPLOYMENT_ID}:${binding?.ownerScopeId ?? LEGACY_DEFAULT_OWNER_SCOPE_ID}`
68
66
  };
69
67
  }
@@ -71,29 +69,6 @@ function isProjectManifestV2(value) {
71
69
  const candidate = value;
72
70
  return candidate?.schemaVersion === 2 && typeof candidate.projectId === "string" && typeof candidate.slug === "string";
73
71
  }
74
- function normalizeLegacyProjectConfig(config) {
75
- return {
76
- schemaVersion: 2,
77
- projectId: config.projectId ?? config.gameId,
78
- slug: config.slug,
79
- bindingKey: LEGACY_DEFAULT_BINDING_KEY,
80
- deploymentId: LEGACY_DEFAULT_DEPLOYMENT_ID,
81
- ownerScopeId: LEGACY_DEFAULT_OWNER_SCOPE_ID,
82
- gameId: config.gameId,
83
- jobId: config.jobId,
84
- agentManaged: config.agentManaged,
85
- workspacePrepared: config.workspacePrepared,
86
- allowCreateGame: config.allowCreateGame,
87
- environment: config.environment,
88
- authoring: config.authoring,
89
- compile: config.compile,
90
- localMaintainerRegistry: config.localMaintainerRegistry,
91
- apiBaseUrl: config.apiBaseUrl,
92
- webBaseUrl: config.webBaseUrl,
93
- packageManifest: config.packageManifest,
94
- environmentManifest: config.environmentManifest
95
- };
96
- }
97
72
  async function loadProjectEnvironmentState(rootDir) {
98
73
  const filePath = path.join(rootDir, PROJECT_DIR_NAME, PROJECT_STATE_FILE);
99
74
  if (!await exists(filePath)) {
@@ -104,15 +79,11 @@ async function loadProjectEnvironmentState(rootDir) {
104
79
  }
105
80
  async function loadProjectConfig(rootDir) {
106
81
  const filePath = path.join(rootDir, PROJECT_DIR_NAME, PROJECT_CONFIG_FILE);
107
- const rawConfig = await readJsonFile(
108
- filePath
109
- );
82
+ const rawConfig = await readJsonFile(filePath);
110
83
  if (!isProjectManifestV2(rawConfig)) {
111
- const migrated = normalizeLegacyProjectConfig(
112
- rawConfig
84
+ throw new Error(
85
+ `Unsupported project config at ${filePath}. Expected schemaVersion 2 with projectId and slug.`
113
86
  );
114
- await updateProjectState(rootDir, migrated);
115
- return migrated;
116
87
  }
117
88
  const state = await loadProjectEnvironmentState(rootDir);
118
89
  const entries = Object.entries(state.bindings);
@@ -155,4 +126,4 @@ export {
155
126
  updateProjectState,
156
127
  findProjectRoot
157
128
  };
158
- //# sourceMappingURL=chunk-M6YNQZCC.mjs.map
129
+ //# sourceMappingURL=chunk-LROY5SN2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/project-config.ts"],"sourcesContent":["import path from \"node:path\";\nimport type {\n ProjectConfig,\n ProjectEnvironmentBindingV1,\n ProjectEnvironmentStateV1,\n ProjectManifestV2,\n} from \"../types.js\";\nimport {\n PROJECT_DIR_NAME,\n PROJECT_CONFIG_FILE,\n PROJECT_STATE_FILE,\n} from \"../constants.js\";\nimport { ensureDir, exists, readJsonFile } from \"../utils/fs.js\";\nimport { atomicWriteFile } from \"../utils/atomic-file.js\";\n\nconst LEGACY_DEFAULT_DEPLOYMENT_ID = \"legacy\";\nconst LEGACY_DEFAULT_OWNER_SCOPE_ID = \"default\";\nconst LEGACY_DEFAULT_BINDING_KEY = `${LEGACY_DEFAULT_DEPLOYMENT_ID}:${LEGACY_DEFAULT_OWNER_SCOPE_ID}`;\n\nfunction normalizeProjectManifest(config: ProjectConfig): ProjectManifestV2 {\n return {\n schemaVersion: 2,\n projectId: config.projectId,\n slug: config.slug,\n };\n}\n\nfunction normalizeProjectBinding(\n config: ProjectConfig,\n): ProjectEnvironmentBindingV1 {\n return {\n deploymentId: config.deploymentId ?? LEGACY_DEFAULT_DEPLOYMENT_ID,\n ownerScopeId: config.ownerScopeId ?? LEGACY_DEFAULT_OWNER_SCOPE_ID,\n remoteHeadDigest: config.remoteHeadDigest,\n jobId: config.jobId,\n agentManaged: config.agentManaged,\n workspacePrepared: config.workspacePrepared,\n allowCreateGame: config.allowCreateGame,\n environment: config.environment,\n authoring: config.authoring,\n compile: config.compile,\n localMaintainerRegistry: config.localMaintainerRegistry,\n apiBaseUrl: config.apiBaseUrl,\n webBaseUrl: config.webBaseUrl,\n packageManifest: config.packageManifest,\n environmentManifest: config.environmentManifest,\n };\n}\n\nfunction normalizeProjectState(\n config: ProjectConfig,\n existing?: ProjectEnvironmentStateV1,\n): ProjectEnvironmentStateV1 {\n const binding = normalizeProjectBinding(config);\n const bindingKey =\n config.bindingKey || `${binding.deploymentId}:${binding.ownerScopeId}`;\n return {\n schemaVersion: 1,\n bindings: {\n ...(existing?.bindings ?? {}),\n [bindingKey]: binding,\n },\n };\n}\n\nfunction mergeManifestAndBinding(\n manifest: ProjectManifestV2,\n binding: ProjectEnvironmentBindingV1 | undefined,\n bindingKey: string | undefined,\n): ProjectConfig {\n return {\n ...manifest,\n ...(binding ?? {\n deploymentId: LEGACY_DEFAULT_DEPLOYMENT_ID,\n ownerScopeId: LEGACY_DEFAULT_OWNER_SCOPE_ID,\n }),\n bindingKey:\n bindingKey ??\n `${binding?.deploymentId ?? LEGACY_DEFAULT_DEPLOYMENT_ID}:${\n binding?.ownerScopeId ?? LEGACY_DEFAULT_OWNER_SCOPE_ID\n }`,\n };\n}\n\nfunction isProjectManifestV2(value: unknown): value is ProjectManifestV2 {\n const candidate = value as Partial<ProjectManifestV2>;\n return (\n candidate?.schemaVersion === 2 &&\n typeof candidate.projectId === \"string\" &&\n typeof candidate.slug === \"string\"\n );\n}\n\nasync function loadProjectEnvironmentState(\n rootDir: string,\n): Promise<ProjectEnvironmentStateV1> {\n const filePath = path.join(rootDir, PROJECT_DIR_NAME, PROJECT_STATE_FILE);\n if (!(await exists(filePath))) {\n return { schemaVersion: 1, bindings: {} };\n }\n const state = await readJsonFile<ProjectEnvironmentStateV1>(filePath);\n return state.schemaVersion === 1 && state.bindings\n ? state\n : { schemaVersion: 1, bindings: {} };\n}\n\nexport async function loadProjectConfig(\n rootDir: string,\n): Promise<ProjectConfig> {\n const filePath = path.join(rootDir, PROJECT_DIR_NAME, PROJECT_CONFIG_FILE);\n const rawConfig = await readJsonFile<ProjectManifestV2>(filePath);\n if (!isProjectManifestV2(rawConfig)) {\n throw new Error(\n `Unsupported project config at ${filePath}. Expected schemaVersion 2 with projectId and slug.`,\n );\n }\n\n const state = await loadProjectEnvironmentState(rootDir);\n const entries = Object.entries(state.bindings);\n const [bindingKey, binding] =\n entries.find(([key]) => key !== LEGACY_DEFAULT_BINDING_KEY) ??\n entries.find(([key]) => key === LEGACY_DEFAULT_BINDING_KEY) ??\n [];\n return mergeManifestAndBinding(rawConfig, binding, bindingKey);\n}\n\nexport async function updateProjectState(\n rootDir: string,\n config: ProjectConfig,\n): Promise<void> {\n const dir = path.join(rootDir, PROJECT_DIR_NAME);\n await ensureDir(dir);\n const existingState = await loadProjectEnvironmentState(rootDir);\n await atomicWriteFile(\n path.join(dir, PROJECT_CONFIG_FILE),\n `${JSON.stringify(normalizeProjectManifest(config), null, 2)}\\n`,\n { mode: 0o644 },\n );\n await atomicWriteFile(\n path.join(dir, PROJECT_STATE_FILE),\n `${JSON.stringify(normalizeProjectState(config, existingState), null, 2)}\\n`,\n { mode: 0o600 },\n );\n}\n\nexport async function updateProjectEnvironmentState(\n rootDir: string,\n config: ProjectConfig,\n): Promise<void> {\n const dir = path.join(rootDir, PROJECT_DIR_NAME);\n await ensureDir(dir);\n const existingState = await loadProjectEnvironmentState(rootDir);\n await atomicWriteFile(\n path.join(dir, PROJECT_STATE_FILE),\n `${JSON.stringify(normalizeProjectState(config, existingState), null, 2)}\\n`,\n { mode: 0o600 },\n );\n}\n\nexport async function findProjectRoot(\n startDir: string,\n): Promise<string | null> {\n let current = path.resolve(startDir);\n for (let i = 0; i < 25; i++) {\n const candidate = path.join(current, PROJECT_DIR_NAME, PROJECT_CONFIG_FILE);\n if (await exists(candidate)) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) break;\n current = parent;\n }\n return null;\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-YE7UAO3T.mjs";
6
6
  import {
7
7
  updateProjectState
8
- } from "./chunk-M6YNQZCC.mjs";
8
+ } from "./chunk-LROY5SN2.mjs";
9
9
  import {
10
10
  writeManifest,
11
11
  writeRule,
@@ -14,7 +14,7 @@ import {
14
14
  import "./chunk-GWRZRWCF.mjs";
15
15
  import {
16
16
  scaffoldStaticWorkspace
17
- } from "./chunk-WLUEMKVV.mjs";
17
+ } from "./chunk-KAA3B4DI.mjs";
18
18
  import "./chunk-XCQQIPCO.mjs";
19
19
  import {
20
20
  ensureDir
@@ -67,8 +67,7 @@ async function materializeWorkspaceProject(input) {
67
67
  function baseProjectConfig(input) {
68
68
  return {
69
69
  schemaVersion: 2,
70
- projectId: input.projectId ?? input.gameId,
71
- gameId: input.gameId,
70
+ projectId: input.projectId,
72
71
  deploymentId: input.deploymentId ?? "legacy",
73
72
  ownerScopeId: input.ownerScopeId ?? "default",
74
73
  bindingKey: input.bindingKey,
@@ -87,4 +86,4 @@ function baseProjectConfig(input) {
87
86
  export {
88
87
  materializeWorkspaceProject
89
88
  };
90
- //# sourceMappingURL=materialize-workspace-RPWQ5PST.mjs.map
89
+ //# sourceMappingURL=materialize-workspace-JBDL6LF4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/project/materialize-workspace.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { GameTopologyManifest } from \"@dreamboard-games/sdk/types\";\nimport type {\n LocalMaintainerRegistryConfig,\n ProjectConfig,\n} from \"../../types.js\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport { writeManifest, writeRule, writeSnapshot } from \"./local-files.js\";\nimport { scaffoldStaticWorkspace } from \"./static-scaffold.js\";\nimport { applyWorkspaceCodegen } from \"./workspace-codegen.js\";\nimport { installWorkspaceDependencies } from \"./workspace-dependencies.js\";\nimport {\n updateProjectAuthoringState,\n updateProjectLocalMaintainerRegistry,\n} from \"./project-state.js\";\nimport { updateProjectState } from \"../../config/project-config.js\";\n\nexport type MaterializeWorkspaceProjectInput = {\n targetDir: string;\n projectId: string;\n slug: string;\n deploymentId?: string;\n ownerScopeId?: string;\n bindingKey?: string;\n remoteHeadDigest?: string;\n apiBaseUrl: string;\n webBaseUrl: string;\n manifest: GameTopologyManifest;\n ruleText: string;\n ruleId?: string;\n manifestId?: string;\n manifestContentHash?: string;\n localMaintainerRegistry?: LocalMaintainerRegistryConfig | null;\n installDependencies?: boolean;\n agentManaged?: boolean;\n workspacePrepared?: boolean;\n allowCreateGame?: boolean;\n jobId?: string;\n packageManifest?: Record<string, unknown>;\n environmentManifest?: Record<string, unknown>;\n};\n\nexport async function materializeWorkspaceProject(\n input: MaterializeWorkspaceProjectInput,\n): Promise<ProjectConfig> {\n const targetDir = path.resolve(input.targetDir);\n await ensureDir(targetDir);\n await writeManifest(targetDir, input.manifest);\n await writeRule(targetDir, input.ruleText);\n\n await scaffoldStaticWorkspace(targetDir, \"new\", {\n localMaintainerRegistry: input.localMaintainerRegistry,\n });\n if (input.installDependencies ?? true) {\n await installWorkspaceDependencies(targetDir);\n await applyWorkspaceCodegen({\n projectRoot: targetDir,\n manifest: input.manifest,\n });\n }\n\n const authoringConfig =\n input.ruleId && input.manifestId && input.manifestContentHash\n ? updateProjectAuthoringState(baseProjectConfig(input), {\n ruleId: input.ruleId,\n manifestId: input.manifestId,\n manifestContentHash: input.manifestContentHash,\n })\n : baseProjectConfig(input);\n const projectConfig = updateProjectLocalMaintainerRegistry(\n authoringConfig,\n input.localMaintainerRegistry ?? undefined,\n );\n await updateProjectState(targetDir, projectConfig);\n await writeSnapshot(targetDir);\n return projectConfig;\n}\n\nfunction baseProjectConfig(\n input: MaterializeWorkspaceProjectInput,\n): ProjectConfig {\n return {\n schemaVersion: 2,\n projectId: input.projectId,\n deploymentId: input.deploymentId ?? \"legacy\",\n ownerScopeId: input.ownerScopeId ?? \"default\",\n bindingKey: input.bindingKey,\n remoteHeadDigest: input.remoteHeadDigest,\n slug: input.slug,\n jobId: input.jobId,\n agentManaged: input.agentManaged,\n workspacePrepared: input.workspacePrepared,\n allowCreateGame: input.allowCreateGame,\n apiBaseUrl: input.apiBaseUrl,\n webBaseUrl: input.webBaseUrl,\n packageManifest: input.packageManifest,\n environmentManifest: input.environmentManifest,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,UAAU;AA0CjB,eAAsB,4BACpB,OACwB;AACxB,QAAM,YAAY,KAAK,QAAQ,MAAM,SAAS;AAC9C,QAAM,UAAU,SAAS;AACzB,QAAM,cAAc,WAAW,MAAM,QAAQ;AAC7C,QAAM,UAAU,WAAW,MAAM,QAAQ;AAEzC,QAAM,wBAAwB,WAAW,OAAO;AAAA,IAC9C,yBAAyB,MAAM;AAAA,EACjC,CAAC;AACD,MAAI,MAAM,uBAAuB,MAAM;AACrC,UAAM,6BAA6B,SAAS;AAC5C,UAAM,sBAAsB;AAAA,MAC1B,aAAa;AAAA,MACb,UAAU,MAAM;AAAA,IAClB,CAAC;AAAA,EACH;AAEA,QAAM,kBACJ,MAAM,UAAU,MAAM,cAAc,MAAM,sBACtC,4BAA4B,kBAAkB,KAAK,GAAG;AAAA,IACpD,QAAQ,MAAM;AAAA,IACd,YAAY,MAAM;AAAA,IAClB,qBAAqB,MAAM;AAAA,EAC7B,CAAC,IACD,kBAAkB,KAAK;AAC7B,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,MAAM,2BAA2B;AAAA,EACnC;AACA,QAAM,mBAAmB,WAAW,aAAa;AACjD,QAAM,cAAc,SAAS;AAC7B,SAAO;AACT;AAEA,SAAS,kBACP,OACe;AACf,SAAO;AAAA,IACL,eAAe;AAAA,IACf,WAAW,MAAM;AAAA,IACjB,cAAc,MAAM,gBAAgB;AAAA,IACpC,cAAc,MAAM,gBAAgB;AAAA,IACpC,YAAY,MAAM;AAAA,IAClB,kBAAkB,MAAM;AAAA,IACxB,MAAM,MAAM;AAAA,IACZ,OAAO,MAAM;AAAA,IACb,cAAc,MAAM;AAAA,IACpB,mBAAmB,MAAM;AAAA,IACzB,iBAAiB,MAAM;AAAA,IACvB,YAAY,MAAM;AAAA,IAClB,YAAY,MAAM;AAAA,IAClB,iBAAiB,MAAM;AAAA,IACvB,qBAAqB,MAAM;AAAA,EAC7B;AACF;","names":[]}
@@ -1316,7 +1316,7 @@ var ShadowReducerRuntime = class {
1316
1316
  this.debug = debug;
1317
1317
  if (typeof gameModuleDefault !== "object" || gameModuleDefault === null || !("contract" in gameModuleDefault)) {
1318
1318
  throw new Error(
1319
- "app/game.ts must export a reducer-native game definition."
1319
+ "app/game.ts must export a reducer-native project definition."
1320
1320
  );
1321
1321
  }
1322
1322
  this.bundle = this.modules.createReducerBundle(gameModuleDefault);
@@ -1704,7 +1704,7 @@ async function createSessionFromScenario(options) {
1704
1704
  return {
1705
1705
  sessionId: snapshot.context.sessionId,
1706
1706
  shortCode: snapshot.context.shortCode,
1707
- gameId: projectIdFromSessionGameSource(snapshot.context.gameSource),
1707
+ projectId: projectIdFromSessionGameSource(snapshot.context.gameSource),
1708
1708
  seed: materialized.seed,
1709
1709
  playerCount: materialized.playerCount,
1710
1710
  setupProfileId: materialized.setupProfileId,
@@ -1780,7 +1780,7 @@ async function materializeScenarioReducerState(options) {
1780
1780
  (entry) => entry.id === options.scenarioId
1781
1781
  );
1782
1782
  const generatedBase2 = scenarioEntry ? generatedBaseStates2?.[baseStateKey(scenarioEntry.base)] : null;
1783
- if (generatedBase2 && generatedBase2.fingerprint.compiledResultId === options.compiledResultId && generatedBase2.fingerprint.gameId === options.gameId) {
1783
+ if (generatedBase2 && generatedBase2.fingerprint.compiledResultId === options.compiledResultId && generatedBase2.fingerprint.projectId === options.projectId) {
1784
1784
  const cached2 = await readMaterializedScenarioCache({
1785
1785
  projectRoot: options.projectRoot,
1786
1786
  baseId: scenarioEntry.base,
@@ -1831,13 +1831,13 @@ async function materializeScenarioReducerState(options) {
1831
1831
  `Generated base artifact for '${base.definition.id}' is stale. Run 'dreamboard test' before using --from-scenario.`
1832
1832
  );
1833
1833
  }
1834
- const canTrustGeneratedFingerprint = options.trustGeneratedFingerprint === true && generatedBase.fingerprint.compiledResultId === options.compiledResultId && generatedBase.fingerprint.gameId === options.gameId;
1834
+ const canTrustGeneratedFingerprint = options.trustGeneratedFingerprint === true && generatedBase.fingerprint.compiledResultId === options.compiledResultId && generatedBase.fingerprint.projectId === options.projectId;
1835
1835
  const current = canTrustGeneratedFingerprint ? generatedBase.fingerprint : await currentFingerprint({
1836
1836
  projectRoot: options.projectRoot,
1837
1837
  base,
1838
1838
  basesById,
1839
1839
  compiledResultId: options.compiledResultId,
1840
- gameId: options.gameId
1840
+ projectId: options.projectId
1841
1841
  });
1842
1842
  if (!canTrustGeneratedFingerprint) {
1843
1843
  validateGeneratedFingerprint({
@@ -1981,7 +1981,7 @@ async function replayScenarioThroughBackend(options) {
1981
1981
  base,
1982
1982
  basesById,
1983
1983
  compiledResultId: options.compiledResultId,
1984
- gameId: options.gameId
1984
+ projectId: options.projectId
1985
1985
  })
1986
1986
  });
1987
1987
  const createInitialTable = typeof manifestContractModule.createInitialTable === "function" ? manifestContractModule.createInitialTable : null;
@@ -2015,7 +2015,7 @@ async function replayScenarioThroughBackend(options) {
2015
2015
  error: sessionError,
2016
2016
  response: sessionResponse
2017
2017
  } = await createProjectSession({
2018
- path: { projectId: options.gameId },
2018
+ path: { projectId: options.projectId },
2019
2019
  body: {
2020
2020
  compiledResultId: options.compiledResultId,
2021
2021
  seed: resolvedBase.seed,
@@ -2075,7 +2075,7 @@ async function replayScenarioThroughBackend(options) {
2075
2075
  return {
2076
2076
  sessionId: session.sessionId,
2077
2077
  shortCode: session.shortCode,
2078
- gameId: projectIdFromSessionGameSource(session.gameSource),
2078
+ projectId: projectIdFromSessionGameSource(session.gameSource),
2079
2079
  seed: resolvedBase.seed,
2080
2080
  playerCount: resolvedBase.players,
2081
2081
  setupProfileId: effectiveSetup.setupProfileId,
@@ -2138,7 +2138,7 @@ async function createScenarioActionPlan(options) {
2138
2138
  base,
2139
2139
  basesById,
2140
2140
  compiledResultId: options.compiledResultId,
2141
- gameId: options.gameId
2141
+ projectId: options.projectId
2142
2142
  })
2143
2143
  });
2144
2144
  const createInitialTable = typeof manifestContractModule.createInitialTable === "function" ? manifestContractModule.createInitialTable : null;
@@ -2195,7 +2195,7 @@ async function createScenarioActionPlan(options) {
2195
2195
  );
2196
2196
  }
2197
2197
  return {
2198
- gameId: options.gameId,
2198
+ projectId: options.projectId,
2199
2199
  seed: resolvedBase.seed,
2200
2200
  playerCount: resolvedBase.players,
2201
2201
  setupProfileId: effectiveSetup.setupProfileId,
@@ -2219,7 +2219,7 @@ async function createActionPlanReplaySession(options) {
2219
2219
  error: sessionError,
2220
2220
  response: sessionResponse
2221
2221
  } = await createProjectSession({
2222
- path: { projectId: options.gameId },
2222
+ path: { projectId: options.projectId },
2223
2223
  body: {
2224
2224
  compiledResultId: options.compiledResultId,
2225
2225
  seed: options.seed,
@@ -2248,7 +2248,7 @@ async function createActionPlanReplaySession(options) {
2248
2248
  return {
2249
2249
  sessionId: session.sessionId,
2250
2250
  shortCode: session.shortCode,
2251
- gameId: projectIdFromSessionGameSource(session.gameSource),
2251
+ projectId: projectIdFromSessionGameSource(session.gameSource),
2252
2252
  seed: options.seed,
2253
2253
  playerCount: options.playerCount,
2254
2254
  setupProfileId: options.setupProfileId ?? null,
@@ -2545,7 +2545,7 @@ async function writeReducerNativeGeneratedFiles(options) {
2545
2545
  uiContractHash,
2546
2546
  setupProfileId: effectiveSetup.setupProfileId,
2547
2547
  compiledResultId: options.compiledResultId,
2548
- gameId: options.gameId,
2548
+ projectId: options.projectId,
2549
2549
  parentBaseId: base.definition.extends ?? null,
2550
2550
  parentFingerprintHash,
2551
2551
  contractFingerprint: contractFingerprintValue
@@ -2648,7 +2648,7 @@ function validateGeneratedFingerprint(options) {
2648
2648
  mismatches.push("manifest changed");
2649
2649
  }
2650
2650
  if (options.generated.appBundleHash !== options.current.appBundleHash) {
2651
- mismatches.push("game reducer bundle changed");
2651
+ mismatches.push("project reducer bundle changed");
2652
2652
  }
2653
2653
  if (options.generated.uiContractHash !== options.current.uiContractHash) {
2654
2654
  mismatches.push("ui contract changed");
@@ -2705,7 +2705,7 @@ async function currentFingerprint(options) {
2705
2705
  base: parentBase,
2706
2706
  basesById: options.basesById,
2707
2707
  compiledResultId: options.compiledResultId,
2708
- gameId: options.gameId
2708
+ projectId: options.projectId
2709
2709
  })
2710
2710
  );
2711
2711
  }
@@ -2728,7 +2728,7 @@ async function currentFingerprint(options) {
2728
2728
  ),
2729
2729
  setupProfileId: effectiveSetup.setupProfileId,
2730
2730
  compiledResultId: options.compiledResultId,
2731
- gameId: options.gameId,
2731
+ projectId: options.projectId,
2732
2732
  parentBaseId: options.base.definition.extends ?? null,
2733
2733
  parentFingerprintHash,
2734
2734
  contractFingerprint: contractFingerprintValue
@@ -2749,7 +2749,7 @@ async function generateReducerNativeArtifacts(options) {
2749
2749
  bases,
2750
2750
  scenarios,
2751
2751
  compiledResultId: options.compiledResultId,
2752
- gameId: options.gameId,
2752
+ projectId: options.projectId,
2753
2753
  debug: options.debug
2754
2754
  });
2755
2755
  return { bases, scenarios };
@@ -2789,7 +2789,7 @@ async function runReducerNativeScenarios(options) {
2789
2789
  bases,
2790
2790
  scenarios,
2791
2791
  compiledResultId: options.compiledResultId,
2792
- gameId: options.gameId,
2792
+ projectId: options.projectId,
2793
2793
  debug: options.debug
2794
2794
  });
2795
2795
  generatedBaseStates = await loadGeneratedBaseStates(options.projectRoot);
@@ -2812,7 +2812,7 @@ async function runReducerNativeScenarios(options) {
2812
2812
  base,
2813
2813
  basesById,
2814
2814
  compiledResultId: options.compiledResultId,
2815
- gameId: options.gameId
2815
+ projectId: options.projectId
2816
2816
  })
2817
2817
  });
2818
2818
  }
@@ -2911,4 +2911,4 @@ export {
2911
2911
  runReducerNativeScenarios,
2912
2912
  writeReducerNativeGeneratedFiles
2913
2913
  };
2914
- //# sourceMappingURL=reducer-native-test-harness-UFMSNNDY.mjs.map
2914
+ //# sourceMappingURL=reducer-native-test-harness-XQUPIT5D.mjs.map