@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.
Files changed (156) hide show
  1. package/README.md +32 -113
  2. package/dist/agent-verifier/agent-workspace-verifier.mjs +2084 -57
  3. package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -1
  4. package/dist/agent-verifier/{chunk-XQXDOBYB.mjs → chunk-4I2WWAPK.mjs} +27 -10
  5. package/dist/agent-verifier/chunk-4I2WWAPK.mjs.map +1 -0
  6. package/dist/agent-verifier/{chunk-C3VW3DTA.mjs → chunk-BWBN2TDJ.mjs} +535 -633
  7. package/dist/agent-verifier/chunk-BWBN2TDJ.mjs.map +1 -0
  8. package/dist/agent-verifier/{chunk-TAEQKBJB.mjs → chunk-GWRZRWCF.mjs} +1 -1
  9. package/dist/agent-verifier/chunk-GWRZRWCF.mjs.map +1 -0
  10. package/dist/agent-verifier/chunk-HUBV22JQ.mjs +89 -0
  11. package/dist/agent-verifier/chunk-HUBV22JQ.mjs.map +1 -0
  12. package/dist/agent-verifier/{chunk-MW2QIWWA.mjs → chunk-KAA3B4DI.mjs} +215 -223
  13. package/dist/agent-verifier/chunk-KAA3B4DI.mjs.map +1 -0
  14. package/dist/agent-verifier/{chunk-27EEIZCI.mjs → chunk-KDAQ4CZY.mjs} +34 -27
  15. package/dist/agent-verifier/chunk-KDAQ4CZY.mjs.map +1 -0
  16. package/dist/agent-verifier/{chunk-IAYRNVUC.mjs → chunk-LMW66VBH.mjs} +2 -13
  17. package/dist/agent-verifier/{chunk-IAYRNVUC.mjs.map → chunk-LMW66VBH.mjs.map} +1 -1
  18. package/dist/agent-verifier/{chunk-776W3UGV.mjs → chunk-LROY5SN2.mjs} +7 -45
  19. package/dist/agent-verifier/chunk-LROY5SN2.mjs.map +1 -0
  20. package/dist/agent-verifier/{chunk-H76MT5UR.mjs → chunk-M7UVBANQ.mjs} +2 -1
  21. package/dist/agent-verifier/chunk-M7UVBANQ.mjs.map +1 -0
  22. package/dist/agent-verifier/{chunk-5NYBTZB4.mjs → chunk-MIRGCMUC.mjs} +112 -26
  23. package/dist/agent-verifier/chunk-MIRGCMUC.mjs.map +1 -0
  24. package/dist/agent-verifier/{chunk-NAK77WXW.mjs → chunk-MYMVXTZT.mjs} +4 -5
  25. package/dist/agent-verifier/chunk-MYMVXTZT.mjs.map +1 -0
  26. package/dist/agent-verifier/chunk-OJFZVGEL.mjs +492 -0
  27. package/dist/agent-verifier/chunk-OJFZVGEL.mjs.map +1 -0
  28. package/dist/agent-verifier/{chunk-XKCJBIRY.mjs → chunk-QD4SQNUP.mjs} +2 -2
  29. package/dist/agent-verifier/{chunk-QBAF7EYR.mjs → chunk-TTB7AIHZ.mjs} +4 -4
  30. package/dist/agent-verifier/{chunk-QBAF7EYR.mjs.map → chunk-TTB7AIHZ.mjs.map} +1 -1
  31. package/dist/agent-verifier/{chunk-F2DIOJJZ.mjs → chunk-XCQQIPCO.mjs} +5 -46
  32. package/dist/agent-verifier/chunk-XCQQIPCO.mjs.map +1 -0
  33. package/dist/agent-verifier/{global-config-NYCSCAUI.mjs → global-config-2NUESNEQ.mjs} +5 -5
  34. package/dist/agent-verifier/{keychain-backend-A3MRWLPF.mjs → keychain-backend-FF4I6ODB.mjs} +11 -6
  35. package/dist/agent-verifier/keychain-backend-FF4I6ODB.mjs.map +1 -0
  36. package/dist/agent-verifier/{local-files-QVJ2H3MH.mjs → local-files-OF4QFISU.mjs} +8 -8
  37. package/dist/agent-verifier/{chunk-UIOLGH4A.mjs → local-typecheck-DHVLM37Z.mjs} +4 -4
  38. package/dist/agent-verifier/local-typecheck-DHVLM37Z.mjs.map +1 -0
  39. package/dist/agent-verifier/{materialize-workspace-OZKOQCSQ.mjs → materialize-workspace-JBDL6LF4.mjs} +22 -22
  40. package/dist/agent-verifier/materialize-workspace-JBDL6LF4.mjs.map +1 -0
  41. package/dist/agent-verifier/{chunk-Z6OZWUIZ.mjs → reducer-bundle-preflight-GLUJKTWU.mjs} +75 -24
  42. package/dist/agent-verifier/reducer-bundle-preflight-GLUJKTWU.mjs.map +1 -0
  43. package/dist/agent-verifier/{chunk-YDIOW2BO.mjs → reducer-contract-preflight-WVQQPW5F.mjs} +7 -6
  44. package/dist/agent-verifier/reducer-contract-preflight-WVQQPW5F.mjs.map +1 -0
  45. package/dist/agent-verifier/{chunk-ON62IGWK.mjs → reducer-native-test-harness-XQUPIT5D.mjs} +480 -703
  46. package/dist/agent-verifier/reducer-native-test-harness-XQUPIT5D.mjs.map +1 -0
  47. package/dist/agent-verifier/static-scaffold-U5DXE23S.mjs +24 -0
  48. package/dist/agent-verifier/{workspace-codegen-WPZHMATU.mjs → workspace-codegen-SPPVHURX.mjs} +3 -3
  49. package/dist/agent-verifier/{workspace-dependencies-B6A2ZX55.mjs → workspace-dependencies-5HEEKZFP.mjs} +5 -3
  50. package/dist/authoring-compatibility-internal.js +12 -0
  51. package/dist/chunk-5IYJOVUA.js +3902 -0
  52. package/dist/chunk-5IYJOVUA.js.map +1 -0
  53. package/dist/chunk-6NYVJYN4.js +313 -0
  54. package/dist/chunk-6NYVJYN4.js.map +1 -0
  55. package/dist/chunk-EQNBQVIW.js +204 -0
  56. package/dist/chunk-EQNBQVIW.js.map +1 -0
  57. package/dist/{chunk-M4SCKH5M.js → chunk-USZAPMQ4.js} +2488 -4993
  58. package/dist/chunk-USZAPMQ4.js.map +1 -0
  59. package/dist/{global-config-YBFEGJQG.js → global-config-RBMW7IVA.js} +3 -2
  60. package/dist/index.js +3099 -6188
  61. package/dist/index.js.map +1 -1
  62. package/dist/internal.js +35 -9
  63. package/dist/internal.js.map +1 -1
  64. package/dist/{keychain-backend-JHTXAKWC.js → keychain-backend-FSNTNTZE.js} +11 -6
  65. package/dist/keychain-backend-FSNTNTZE.js.map +1 -0
  66. package/package.json +9 -19
  67. package/release/authoring-release-set.json +38 -0
  68. package/skills/dreamboard/SKILL.md +32 -30
  69. package/skills/dreamboard/references/building-your-first-game.md +16 -16
  70. package/skills/dreamboard/references/cli.md +54 -54
  71. package/skills/dreamboard/references/manifest-authoring.md +11 -3
  72. package/skills/dreamboard/references/quickstart.md +19 -16
  73. package/skills/dreamboard/references/testing.md +6 -13
  74. package/dist/agent-verifier/chunk-27EEIZCI.mjs.map +0 -1
  75. package/dist/agent-verifier/chunk-5NYBTZB4.mjs.map +0 -1
  76. package/dist/agent-verifier/chunk-776W3UGV.mjs.map +0 -1
  77. package/dist/agent-verifier/chunk-C3VW3DTA.mjs.map +0 -1
  78. package/dist/agent-verifier/chunk-F2DIOJJZ.mjs.map +0 -1
  79. package/dist/agent-verifier/chunk-G42BGGG2.mjs +0 -70
  80. package/dist/agent-verifier/chunk-G42BGGG2.mjs.map +0 -1
  81. package/dist/agent-verifier/chunk-H76MT5UR.mjs.map +0 -1
  82. package/dist/agent-verifier/chunk-IDVQXGAO.mjs +0 -222
  83. package/dist/agent-verifier/chunk-IDVQXGAO.mjs.map +0 -1
  84. package/dist/agent-verifier/chunk-JO5AMVZU.mjs +0 -1744
  85. package/dist/agent-verifier/chunk-JO5AMVZU.mjs.map +0 -1
  86. package/dist/agent-verifier/chunk-KDBSVLCF.mjs +0 -624
  87. package/dist/agent-verifier/chunk-KDBSVLCF.mjs.map +0 -1
  88. package/dist/agent-verifier/chunk-MW2QIWWA.mjs.map +0 -1
  89. package/dist/agent-verifier/chunk-NAK77WXW.mjs.map +0 -1
  90. package/dist/agent-verifier/chunk-ON62IGWK.mjs.map +0 -1
  91. package/dist/agent-verifier/chunk-QZH6IEZS.mjs +0 -39
  92. package/dist/agent-verifier/chunk-QZH6IEZS.mjs.map +0 -1
  93. package/dist/agent-verifier/chunk-TAEQKBJB.mjs.map +0 -1
  94. package/dist/agent-verifier/chunk-UIOLGH4A.mjs.map +0 -1
  95. package/dist/agent-verifier/chunk-XQXDOBYB.mjs.map +0 -1
  96. package/dist/agent-verifier/chunk-YDIOW2BO.mjs.map +0 -1
  97. package/dist/agent-verifier/chunk-Z6OZWUIZ.mjs.map +0 -1
  98. package/dist/agent-verifier/compile-576O7TYP.mjs +0 -312
  99. package/dist/agent-verifier/compile-576O7TYP.mjs.map +0 -1
  100. package/dist/agent-verifier/keychain-backend-A3MRWLPF.mjs.map +0 -1
  101. package/dist/agent-verifier/local-typecheck-2JWG5IGL.mjs +0 -10
  102. package/dist/agent-verifier/materialize-workspace-OZKOQCSQ.mjs.map +0 -1
  103. package/dist/agent-verifier/reducer-bundle-preflight-7NYZF5ZT.mjs +0 -20
  104. package/dist/agent-verifier/reducer-contract-preflight-COD2CO22.mjs +0 -11
  105. package/dist/agent-verifier/reducer-native-test-harness-QC7HZUK4.mjs +0 -50
  106. package/dist/agent-verifier/static-scaffold-JBUE3ROP.mjs +0 -27
  107. package/dist/agent-verifier/sync-C6S3OGCD.mjs +0 -588
  108. package/dist/agent-verifier/sync-C6S3OGCD.mjs.map +0 -1
  109. package/dist/agent-verifier/test-Y5UGQV7J.mjs +0 -353
  110. package/dist/agent-verifier/test-Y5UGQV7J.mjs.map +0 -1
  111. package/dist/agent-verifier/workspace-codegen-WPZHMATU.mjs.map +0 -1
  112. package/dist/agent-verifier/workspace-dependencies-B6A2ZX55.mjs.map +0 -1
  113. package/dist/chunk-3NRROR4P.js +0 -432
  114. package/dist/chunk-3NRROR4P.js.map +0 -1
  115. package/dist/chunk-M4SCKH5M.js.map +0 -1
  116. package/dist/dev-host/components/drawer.tsx +0 -132
  117. package/dist/dev-host/components/input.tsx +0 -21
  118. package/dist/dev-host/dev-api-proxy-plugin.ts +0 -328
  119. package/dist/dev-host/dev-author-dom-warnings.ts +0 -100
  120. package/dist/dev-host/dev-diagnostics.ts +0 -62
  121. package/dist/dev-host/dev-fallback-stylesheet.ts +0 -53
  122. package/dist/dev-host/dev-hmr-guard-plugin.ts +0 -47
  123. package/dist/dev-host/dev-host-controller.ts +0 -674
  124. package/dist/dev-host/dev-host-player-query.ts +0 -17
  125. package/dist/dev-host/dev-host-session-transport.ts +0 -52
  126. package/dist/dev-host/dev-host-storage.ts +0 -56
  127. package/dist/dev-host/dev-log-relay-plugin.ts +0 -510
  128. package/dist/dev-host/dev-runtime-config.ts +0 -14
  129. package/dist/dev-host/dev-runtime-platform.ts +0 -335
  130. package/dist/dev-host/dev-virtual-modules-plugin.ts +0 -64
  131. package/dist/dev-host/host-main.css +0 -224
  132. package/dist/dev-host/host-main.tsx +0 -948
  133. package/dist/dev-host/index.html +0 -56
  134. package/dist/dev-host/lib/utils.ts +0 -6
  135. package/dist/dev-host/plugin-main.ts +0 -61
  136. package/dist/dev-host/plugin.html +0 -24
  137. package/dist/dev-host/shared-styles.css +0 -144
  138. package/dist/dev-host/start-dev-server.ts +0 -140
  139. package/dist/dev-host/virtual-modules.d.ts +0 -27
  140. package/dist/global-config-YBFEGJQG.js.map +0 -1
  141. package/dist/keychain-backend-JHTXAKWC.js.map +0 -1
  142. package/skills/dreamboard/scripts/events-extract.mjs +0 -218
  143. /package/dist/agent-verifier/{chunk-XKCJBIRY.mjs.map → chunk-QD4SQNUP.mjs.map} +0 -0
  144. /package/dist/agent-verifier/{global-config-NYCSCAUI.mjs.map → global-config-2NUESNEQ.mjs.map} +0 -0
  145. /package/dist/agent-verifier/{local-files-QVJ2H3MH.mjs.map → local-files-OF4QFISU.mjs.map} +0 -0
  146. /package/dist/agent-verifier/{local-typecheck-2JWG5IGL.mjs.map → static-scaffold-U5DXE23S.mjs.map} +0 -0
  147. /package/dist/agent-verifier/{reducer-bundle-preflight-7NYZF5ZT.mjs.map → workspace-codegen-SPPVHURX.mjs.map} +0 -0
  148. /package/dist/agent-verifier/{reducer-contract-preflight-COD2CO22.mjs.map → workspace-dependencies-5HEEKZFP.mjs.map} +0 -0
  149. /package/dist/{agent-verifier/reducer-native-test-harness-QC7HZUK4.mjs.map → authoring-compatibility-internal.js.map} +0 -0
  150. /package/dist/{agent-verifier/static-scaffold-JBUE3ROP.mjs.map → global-config-RBMW7IVA.js.map} +0 -0
  151. /package/{dist/scaffold → scaffold}/assets/static/app/tsconfig.framework.json +0 -0
  152. /package/{dist/scaffold → scaffold}/assets/static/app/tsconfig.json +0 -0
  153. /package/{dist/scaffold → scaffold}/assets/static/ui/index.tsx +0 -0
  154. /package/{dist/scaffold → scaffold}/assets/static/ui/style.css +0 -0
  155. /package/{dist/scaffold → scaffold}/assets/static/ui/tsconfig.framework.json +0 -0
  156. /package/{dist/scaffold → scaffold}/assets/static/ui/tsconfig.json +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/repo-root.ts","../../src/utils/repo-local-package-resolution.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction isRepoRoot(candidate: string): boolean {\n return (\n existsSync(path.join(candidate, \"pnpm-workspace.yaml\")) &&\n existsSync(path.join(candidate, \"apps\", \"dreamboard-cli\", \"package.json\"))\n );\n}\n\nexport function resolveCliRepoRoot(importMetaUrl: string = import.meta.url) {\n let current = path.dirname(fileURLToPath(importMetaUrl));\n\n while (true) {\n if (isRepoRoot(current)) {\n return current;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n throw new Error(\n `Could not resolve Dreamboard CLI repo root from ${importMetaUrl}.`,\n );\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport type { Plugin } from \"esbuild\";\nimport { resolveCliRepoRoot } from \"./repo-root.js\";\n\ntype RepoLocalPackageInfo = {\n rootDir: string;\n exports: unknown;\n};\n\ntype RepoLocalPackageResolutionOptions = {\n repoRoot?: string;\n};\n\nconst PACKAGE_INFO_CACHE = new Map<string, Map<string, RepoLocalPackageInfo>>();\n\nfunction normalizeRepoRoot(\n options?: RepoLocalPackageResolutionOptions,\n): string {\n return options?.repoRoot ?? resolveCliRepoRoot(import.meta.url);\n}\n\nfunction readPackageInfos(repoRoot: string): Map<string, RepoLocalPackageInfo> {\n const cached = PACKAGE_INFO_CACHE.get(repoRoot);\n if (cached) {\n return cached;\n }\n\n const packageInfos = new Map<string, RepoLocalPackageInfo>();\n const addPackageInfo = (packageRoot: string): void => {\n const packageJsonPath = path.join(packageRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n return;\n }\n\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as {\n name?: string;\n exports?: unknown;\n };\n if (\n !parsed.name ||\n (!parsed.name.startsWith(\"@dreamboard/\") &&\n !parsed.name.startsWith(\"@dreamboard-games/\")) ||\n parsed.exports === undefined\n ) {\n return;\n }\n\n packageInfos.set(parsed.name, {\n rootDir: packageRoot,\n exports: parsed.exports,\n });\n };\n\n for (const workspaceDirName of [\"packages\", \"apps\"]) {\n const workspaceRoot = path.join(repoRoot, workspaceDirName);\n if (!existsSync(workspaceRoot)) {\n continue;\n }\n\n for (const entry of readdirSync(workspaceRoot, { withFileTypes: true })) {\n if (!entry.isDirectory()) {\n continue;\n }\n addPackageInfo(path.join(workspaceRoot, entry.name));\n }\n }\n\n for (const nodeModulesRoot of [\n path.join(repoRoot, \"node_modules\"),\n path.join(repoRoot, \"apps\", \"dreamboard-cli\", \"node_modules\"),\n ]) {\n for (const scopeName of [\"@dreamboard\", \"@dreamboard-games\"]) {\n const scopeRoot = path.join(nodeModulesRoot, scopeName);\n if (!existsSync(scopeRoot)) {\n continue;\n }\n\n for (const entry of readdirSync(scopeRoot, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) {\n continue;\n }\n addPackageInfo(path.join(scopeRoot, entry.name));\n }\n }\n }\n\n PACKAGE_INFO_CACHE.set(repoRoot, packageInfos);\n return packageInfos;\n}\n\nfunction parseDreamboardPackageSpecifier(specifier: string): {\n packageName: string;\n subpath: string;\n} | null {\n if (\n !specifier.startsWith(\"@dreamboard/\") &&\n !specifier.startsWith(\"@dreamboard-games/\")\n ) {\n return null;\n }\n\n const segments = specifier.split(\"/\");\n if (segments.length < 2) {\n return null;\n }\n\n const packageName = `${segments[0]}/${segments[1]}`;\n const subpath =\n segments.length === 2 ? \".\" : `./${segments.slice(2).join(\"/\")}`;\n return { packageName, subpath };\n}\n\nfunction resolveSourceTarget(exportEntry: unknown): string | null {\n if (typeof exportEntry === \"string\") {\n return exportEntry;\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"dreamboard-source\" in exportEntry &&\n typeof (exportEntry as { \"dreamboard-source\"?: unknown })[\n \"dreamboard-source\"\n ] === \"string\"\n ) {\n return (exportEntry as { \"dreamboard-source\": string })[\n \"dreamboard-source\"\n ];\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"bun\" in exportEntry &&\n typeof (exportEntry as { bun?: unknown }).bun === \"string\"\n ) {\n return (exportEntry as { bun: string }).bun;\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"import\" in exportEntry &&\n typeof (exportEntry as { import?: unknown }).import === \"string\"\n ) {\n return (exportEntry as { import: string }).import;\n }\n return null;\n}\n\nfunction resolveSourceTargetForSubpath(options: {\n exportsField: unknown;\n subpath: string;\n}): string | null {\n if (\n typeof options.exportsField !== \"object\" ||\n options.exportsField === null ||\n Array.isArray(options.exportsField)\n ) {\n return options.subpath === \".\"\n ? resolveSourceTarget(options.exportsField)\n : null;\n }\n\n const exportsMap = options.exportsField as Record<string, unknown>;\n if (options.subpath === \".\") {\n return (\n resolveSourceTarget(exportsMap[\".\"]) ?? resolveSourceTarget(exportsMap)\n );\n }\n const exactTarget = resolveSourceTarget(exportsMap[options.subpath]);\n if (exactTarget) {\n return exactTarget;\n }\n\n const wildcardEntries = Object.entries(exportsMap)\n .filter(([key]) => key.includes(\"*\"))\n .sort(([left], [right]) => right.length - left.length);\n for (const [pattern, exportEntry] of wildcardEntries) {\n const starIndex = pattern.indexOf(\"*\");\n const prefix = pattern.slice(0, starIndex);\n const suffix = pattern.slice(starIndex + 1);\n if (\n !options.subpath.startsWith(prefix) ||\n !options.subpath.endsWith(suffix)\n ) {\n continue;\n }\n\n const wildcardValue = options.subpath.slice(\n prefix.length,\n options.subpath.length - suffix.length,\n );\n const targetPattern = resolveSourceTarget(exportEntry);\n if (!targetPattern) {\n continue;\n }\n return targetPattern.replace(\"*\", wildcardValue);\n }\n\n return null;\n}\n\nexport function resolveRepoLocalPackageSource(\n specifier: string,\n options?: RepoLocalPackageResolutionOptions,\n): string | null {\n const parsedSpecifier = parseDreamboardPackageSpecifier(specifier);\n if (!parsedSpecifier) {\n return null;\n }\n\n let repoRoot: string;\n try {\n repoRoot = normalizeRepoRoot(options);\n } catch {\n return null;\n }\n\n const packageInfo = readPackageInfos(repoRoot).get(\n parsedSpecifier.packageName,\n );\n if (!packageInfo) {\n return null;\n }\n\n const sourceTarget = resolveSourceTargetForSubpath({\n exportsField: packageInfo.exports,\n subpath: parsedSpecifier.subpath,\n });\n if (!sourceTarget) {\n return null;\n }\n\n return path.join(packageInfo.rootDir, sourceTarget);\n}\n\nconst cliPackageRequire = createRequire(import.meta.url);\n\nfunction resolvableFromDirectory(\n specifier: string,\n directory: string,\n): boolean {\n try {\n createRequire(path.join(directory, \"noop.js\")).resolve(specifier);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve a `@dreamboard-games/*` specifier against the CLI package's own\n * dependency tree. This keeps manifest evaluation working in workspaces that\n * have not installed their dependencies yet (for example right after\n * `dreamboard clone`), where the installed CLI's pinned SDK is the only\n * available copy.\n */\nfunction resolveCliBundledPackage(specifier: string): string | null {\n try {\n return cliPackageRequire.resolve(specifier);\n } catch {\n return null;\n }\n}\n\nexport function createRepoLocalPackageResolutionPlugin(\n options?: RepoLocalPackageResolutionOptions,\n): Plugin {\n return {\n name: \"dreamboard-repo-local-package-resolution\",\n setup(build) {\n build.onResolve({ filter: /^@dreamboard(?:-games)?\\// }, (args) => {\n const resolvedPath = resolveRepoLocalPackageSource(args.path, options);\n if (resolvedPath) {\n return { path: resolvedPath };\n }\n // Prefer the workspace's own installed copy when present; returning\n // null lets esbuild perform its normal node_modules resolution.\n if (resolvableFromDirectory(args.path, args.resolveDir)) {\n return null;\n }\n const bundledPath = resolveCliBundledPackage(args.path);\n if (bundledPath) {\n return { path: bundledPath };\n }\n return null;\n });\n },\n };\n}\n"],"mappings":"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","names":["existsSync","path","path","existsSync"]}
1
+ {"version":3,"sources":["../../src/utils/repo-root.ts","../../src/utils/repo-local-package-resolution.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction isRepoRoot(candidate: string): boolean {\n return (\n existsSync(path.join(candidate, \"pnpm-workspace.yaml\")) &&\n existsSync(path.join(candidate, \"apps\", \"dreamboard-cli\", \"package.json\"))\n );\n}\n\nexport function resolveCliRepoRoot(importMetaUrl: string = import.meta.url) {\n let current = path.dirname(fileURLToPath(importMetaUrl));\n\n while (true) {\n if (isRepoRoot(current)) {\n return current;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n throw new Error(\n `Could not resolve Dreamboard CLI repo root from ${importMetaUrl}.`,\n );\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport type { Plugin } from \"esbuild\";\nimport { resolveCliRepoRoot } from \"./repo-root.js\";\n\ntype RepoLocalPackageInfo = {\n rootDir: string;\n exports: unknown;\n};\n\ntype RepoLocalPackageResolutionOptions = {\n repoRoot?: string;\n};\n\nconst PACKAGE_INFO_CACHE = new Map<string, Map<string, RepoLocalPackageInfo>>();\n\nfunction normalizeRepoRoot(\n options?: RepoLocalPackageResolutionOptions,\n): string {\n return options?.repoRoot ?? resolveCliRepoRoot(import.meta.url);\n}\n\nfunction readPackageInfos(repoRoot: string): Map<string, RepoLocalPackageInfo> {\n const cached = PACKAGE_INFO_CACHE.get(repoRoot);\n if (cached) {\n return cached;\n }\n\n const packageInfos = new Map<string, RepoLocalPackageInfo>();\n const addPackageInfo = (packageRoot: string): void => {\n const packageJsonPath = path.join(packageRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n return;\n }\n\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as {\n name?: string;\n exports?: unknown;\n };\n if (\n !parsed.name ||\n (!parsed.name.startsWith(\"@dreamboard/\") &&\n !parsed.name.startsWith(\"@dreamboard-games/\")) ||\n parsed.exports === undefined\n ) {\n return;\n }\n\n packageInfos.set(parsed.name, {\n rootDir: packageRoot,\n exports: parsed.exports,\n });\n };\n\n for (const workspaceDirName of [\"packages\", \"apps\"]) {\n const workspaceRoot = path.join(repoRoot, workspaceDirName);\n if (!existsSync(workspaceRoot)) {\n continue;\n }\n\n for (const entry of readdirSync(workspaceRoot, { withFileTypes: true })) {\n if (!entry.isDirectory()) {\n continue;\n }\n addPackageInfo(path.join(workspaceRoot, entry.name));\n }\n }\n\n for (const nodeModulesRoot of [\n path.join(repoRoot, \"node_modules\"),\n path.join(repoRoot, \"apps\", \"dreamboard-cli\", \"node_modules\"),\n ]) {\n for (const scopeName of [\"@dreamboard\", \"@dreamboard-games\"]) {\n const scopeRoot = path.join(nodeModulesRoot, scopeName);\n if (!existsSync(scopeRoot)) {\n continue;\n }\n\n for (const entry of readdirSync(scopeRoot, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) {\n continue;\n }\n addPackageInfo(path.join(scopeRoot, entry.name));\n }\n }\n }\n\n PACKAGE_INFO_CACHE.set(repoRoot, packageInfos);\n return packageInfos;\n}\n\nfunction parseDreamboardPackageSpecifier(specifier: string): {\n packageName: string;\n subpath: string;\n} | null {\n if (\n !specifier.startsWith(\"@dreamboard/\") &&\n !specifier.startsWith(\"@dreamboard-games/\")\n ) {\n return null;\n }\n\n const segments = specifier.split(\"/\");\n if (segments.length < 2) {\n return null;\n }\n\n const packageName = `${segments[0]}/${segments[1]}`;\n const subpath =\n segments.length === 2 ? \".\" : `./${segments.slice(2).join(\"/\")}`;\n return { packageName, subpath };\n}\n\nfunction resolveSourceTarget(exportEntry: unknown): string | null {\n if (typeof exportEntry === \"string\") {\n return exportEntry;\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"dreamboard-source\" in exportEntry &&\n typeof (exportEntry as { \"dreamboard-source\"?: unknown })[\n \"dreamboard-source\"\n ] === \"string\"\n ) {\n return (exportEntry as { \"dreamboard-source\": string })[\n \"dreamboard-source\"\n ];\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"bun\" in exportEntry &&\n typeof (exportEntry as { bun?: unknown }).bun === \"string\"\n ) {\n return (exportEntry as { bun: string }).bun;\n }\n if (\n typeof exportEntry === \"object\" &&\n exportEntry !== null &&\n \"import\" in exportEntry &&\n typeof (exportEntry as { import?: unknown }).import === \"string\"\n ) {\n return (exportEntry as { import: string }).import;\n }\n return null;\n}\n\nfunction resolveSourceTargetForSubpath(options: {\n exportsField: unknown;\n subpath: string;\n}): string | null {\n if (\n typeof options.exportsField !== \"object\" ||\n options.exportsField === null ||\n Array.isArray(options.exportsField)\n ) {\n return options.subpath === \".\"\n ? resolveSourceTarget(options.exportsField)\n : null;\n }\n\n const exportsMap = options.exportsField as Record<string, unknown>;\n if (options.subpath === \".\") {\n return (\n resolveSourceTarget(exportsMap[\".\"]) ?? resolveSourceTarget(exportsMap)\n );\n }\n const exactTarget = resolveSourceTarget(exportsMap[options.subpath]);\n if (exactTarget) {\n return exactTarget;\n }\n\n const wildcardEntries = Object.entries(exportsMap)\n .filter(([key]) => key.includes(\"*\"))\n .sort(([left], [right]) => right.length - left.length);\n for (const [pattern, exportEntry] of wildcardEntries) {\n const starIndex = pattern.indexOf(\"*\");\n const prefix = pattern.slice(0, starIndex);\n const suffix = pattern.slice(starIndex + 1);\n if (\n !options.subpath.startsWith(prefix) ||\n !options.subpath.endsWith(suffix)\n ) {\n continue;\n }\n\n const wildcardValue = options.subpath.slice(\n prefix.length,\n options.subpath.length - suffix.length,\n );\n const targetPattern = resolveSourceTarget(exportEntry);\n if (!targetPattern) {\n continue;\n }\n return targetPattern.replace(\"*\", wildcardValue);\n }\n\n return null;\n}\n\nexport function resolveRepoLocalPackageSource(\n specifier: string,\n options?: RepoLocalPackageResolutionOptions,\n): string | null {\n const parsedSpecifier = parseDreamboardPackageSpecifier(specifier);\n if (!parsedSpecifier) {\n return null;\n }\n\n let repoRoot: string;\n try {\n repoRoot = normalizeRepoRoot(options);\n } catch {\n return null;\n }\n\n const packageInfo = readPackageInfos(repoRoot).get(\n parsedSpecifier.packageName,\n );\n if (!packageInfo) {\n return null;\n }\n\n const sourceTarget = resolveSourceTargetForSubpath({\n exportsField: packageInfo.exports,\n subpath: parsedSpecifier.subpath,\n });\n if (!sourceTarget) {\n return null;\n }\n\n return path.join(packageInfo.rootDir, sourceTarget);\n}\n\nconst cliPackageRequire = createRequire(import.meta.url);\n\nfunction resolvableFromDirectory(\n specifier: string,\n directory: string,\n): boolean {\n try {\n createRequire(path.join(directory, \"noop.js\")).resolve(specifier);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve a `@dreamboard-games/*` specifier against the CLI package's own\n * dependency tree. This keeps manifest evaluation working in workspaces that\n * have not installed their dependencies yet (for example right after\n * `dreamboard clone`), where the installed CLI's pinned SDK is the only\n * available copy.\n */\nfunction resolveCliBundledPackage(specifier: string): string | null {\n try {\n return cliPackageRequire.resolve(specifier);\n } catch {\n return null;\n }\n}\n\nexport function createRepoLocalPackageResolutionPlugin(\n options?: RepoLocalPackageResolutionOptions,\n): Plugin {\n return {\n name: \"dreamboard-repo-local-package-resolution\",\n setup(build) {\n build.onResolve({ filter: /^@dreamboard(?:-games)?\\// }, (args) => {\n // Prefer the workspace's own installed copy when present; returning\n // null lets esbuild perform its normal node_modules resolution.\n if (resolvableFromDirectory(args.path, args.resolveDir)) {\n return null;\n }\n const resolvedPath = resolveRepoLocalPackageSource(args.path, options);\n if (resolvedPath) {\n return { path: resolvedPath };\n }\n const bundledPath = resolveCliBundledPackage(args.path);\n if (bundledPath) {\n return { path: bundledPath };\n }\n return null;\n });\n },\n };\n}\n"],"mappings":"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","names":["existsSync","path","path","existsSync"]}
@@ -30,7 +30,6 @@ import {
30
30
  import type {
31
31
  BaseDefinition,
32
32
  ScenarioDefinition,
33
- TestRunner,
34
33
  } from "./generated/testing-contract";
35
34
 
36
35
  export * from "./generated/testing-contract";
@@ -53,11 +52,10 @@ export function defineBase<const Definition extends BaseDefinition>(
53
52
  * \`phase\` / \`stage\` to the manifest-derived literal types.
54
53
  */
55
54
  export function defineScenario<
56
- const Runners extends readonly TestRunner[] = readonly ["reducer"],
57
55
  const Phase extends PhaseName | undefined = undefined,
58
56
  >(
59
- definition: ScenarioDefinition<Runners, Phase>,
60
- ): ScenarioDefinition<Runners, Phase> {
57
+ definition: ScenarioDefinition<Phase>,
58
+ ): ScenarioDefinition<Phase> {
61
59
  return definition;
62
60
  }
63
61
 
@@ -107,10 +105,7 @@ import {
107
105
  type PhaseName,
108
106
  type StageName as WorkspaceStageName,
109
107
  } from "../../shared/generated/ui-contract";
110
- import type {
111
- ExpectFn as SharedExpectFn,
112
- TestRunner as SharedTestRunner,
113
- } from "@dreamboard-games/sdk/testing";
108
+ import type { ExpectFn as SharedExpectFn } from "@dreamboard-games/sdk/testing";
114
109
  import type { InteractionDescriptor } from "@dreamboard-games/sdk/runtime";
115
110
  import { BASE_STATES } from "./base-states.generated";
116
111
 
@@ -143,14 +138,12 @@ export type InteractionExplanation = {
143
138
  eligibleCount: number | "lazy";
144
139
  }>;
145
140
  };
146
- export type TestRunner = SharedTestRunner;
147
141
  export type ExpectFn = SharedExpectFn;
148
142
  export type KnownRejectionCode = ${renderLiteralUnion(rejectionCodes)};
149
143
  export type RejectionCode = [KnownRejectionCode] extends [never]
150
144
  ? string
151
145
  : KnownRejectionCode;
152
146
 
153
- type DefaultRunners = readonly ["reducer"];
154
147
  type PhaseTaggedView<Phase extends PhaseName> = Extract<
155
148
  GameView,
156
149
  { phase: Phase } | { currentPhase: Phase } | { state: Phase }
@@ -172,41 +165,10 @@ type InteractionParamsForKey<Key extends InteractionKey> =
172
165
  type InteractionParamsOfId<Id extends InteractionId> =
173
166
  InteractionParamsForKey<InteractionKeyForId<Id>>;
174
167
 
175
- export interface BrowserRunnerSnapshot {
176
- sessionId: string | null;
177
- shortCode: string | null;
178
- version: number;
179
- currentPhase: string | null;
180
- controllingPlayerId: string;
181
- controllablePlayerIds: string[];
182
- view: unknown;
183
- availableInteractions?: string[];
184
- }
185
-
186
- export interface BrowserRunnerBridge {
187
- snapshot(): Promise<BrowserRunnerSnapshot>;
188
- submitInteraction(
189
- playerId: PlayerId,
190
- interactionId: string,
191
- params: unknown,
192
- ): Promise<void>;
193
- }
194
-
195
- export interface BrowserRunnerDriver {
196
- onReady?(bridge: BrowserRunnerBridge): Promise<void> | void;
197
- interaction?(
198
- bridge: BrowserRunnerBridge,
199
- input: { playerId: PlayerId; interactionId: string; params: unknown },
200
- ): Promise<boolean | void> | boolean | void;
201
- }
202
-
203
168
  export interface ScenarioGameApi {
204
169
  start(): Promise<void>;
205
170
  /**
206
171
  * Patch the reducer snapshot for deterministic setup-heavy scenarios.
207
- * This is limited to reducer snapshot materialization and is rejected by
208
- * live replay/browser runners so authored gameplay verification still
209
- * submits real interactions.
210
172
  */
211
173
  patchState(mutator: (state: Record<string, unknown>) => void): Promise<void>;
212
174
  /**
@@ -258,7 +220,6 @@ export type ScenarioContext<
258
220
  };
259
221
 
260
222
  export type ScenarioThenContext<
261
- _Runners extends readonly TestRunner[] = DefaultRunners,
262
223
  Phase extends PhaseName | undefined = undefined,
263
224
  > = ScenarioContext<Phase>;
264
225
 
@@ -272,17 +233,15 @@ export interface BaseDefinition {
272
233
  }
273
234
 
274
235
  export interface ScenarioDefinition<
275
- Runners extends readonly TestRunner[] = DefaultRunners,
276
236
  Phase extends PhaseName | undefined = undefined,
277
237
  > {
278
238
  id: string;
279
239
  description?: string;
280
240
  from: BaseId | string;
281
- runners?: Runners;
282
241
  phase?: Phase;
283
242
  stage?: Phase extends PhaseName ? WorkspaceStageName<Phase> : never;
284
243
  when: (ctx: ScenarioContext<Phase>) => void | Promise<void>;
285
- then: (ctx: ScenarioThenContext<Runners, Phase>) => void | Promise<void>;
244
+ then: (ctx: ScenarioThenContext<Phase>) => void | Promise<void>;
286
245
  }
287
246
 
288
247
  export type {
@@ -299,4 +258,4 @@ export {
299
258
  REDUCER_TESTING_TYPES_WRAPPER_CONTENT,
300
259
  buildReducerTestingContractContent
301
260
  };
302
- //# sourceMappingURL=chunk-F2DIOJJZ.mjs.map
261
+ //# sourceMappingURL=chunk-XCQQIPCO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/templates/testing-types-content.ts"],"sourcesContent":["const DEFAULT_REJECTION_CODES = [\n \"NOT_YOUR_TURN\",\n \"action-unavailable\",\n \"invalid-action-params\",\n \"prompt-not-owned\",\n] as const;\n\nfunction renderLiteralUnion(values: readonly string[]): string {\n if (values.length === 0) {\n return \"never\";\n }\n return values.map((value) => JSON.stringify(value)).join(\" | \");\n}\n\nexport const REDUCER_TESTING_TYPES_WRAPPER_CONTENT = `\\\n// Generated by dreamboard — do not edit by hand.\nimport game from \"../app/game\";\nimport {\n contractFingerprint,\n createReducerBundle,\n} from \"@dreamboard-games/sdk/reducer\";\nimport { createTestRuntime as createDreamboardTestRuntime } from \"@dreamboard-games/sdk/testing\";\nimport type { CreateTestRuntimeOptions } from \"@dreamboard-games/sdk/testing\";\nimport { literals } from \"../shared/manifest-contract\";\nimport type { PhaseName } from \"../shared/generated/ui-contract\";\nimport {\n BASE_STATES,\n BASE_STATES_CONTRACT_FINGERPRINT,\n} from \"./generated/base-states.generated\";\nimport type {\n BaseDefinition,\n ScenarioDefinition,\n} from \"./generated/testing-contract\";\n\nexport * from \"./generated/testing-contract\";\n\n/**\n * Workspace-narrowed \\`defineBase\\` wrapper. Accepts the generated\n * \\`BaseDefinition\\` so \\`setup({ seat, game })\\` is typed against the\n * workspace's player ids and interaction contract.\n */\nexport function defineBase<const Definition extends BaseDefinition>(\n definition: Definition,\n): Definition {\n return definition;\n}\n\n/**\n * Workspace-narrowed \\`defineScenario\\` wrapper. The generated\n * \\`ScenarioDefinition\\` narrows \\`ctx.view(playerId)\\` in \\`then\\` based on\n * the declared \\`phase\\`, keeps \\`when\\` union-typed, and constrains\n * \\`phase\\` / \\`stage\\` to the manifest-derived literal types.\n */\nexport function defineScenario<\n const Phase extends PhaseName | undefined = undefined,\n>(\n definition: ScenarioDefinition<Phase>,\n): ScenarioDefinition<Phase> {\n return definition;\n}\n\nexport function createTestRuntime(options: {\n baseId: keyof typeof BASE_STATES & string;\n phase?: PhaseName;\n controllingPlayerId?: (typeof literals.playerIds)[number];\n userId?: string | null;\n}) {\n const reducerBundle =\n createReducerBundle(game) satisfies CreateTestRuntimeOptions[\"bundle\"];\n const baseStates =\n BASE_STATES satisfies CreateTestRuntimeOptions[\"baseStates\"];\n const runtime = createDreamboardTestRuntime({\n baseId: options.baseId,\n baseStates,\n bundle: reducerBundle,\n contractFingerprint: contractFingerprint(game).value,\n expectedBaseStateFingerprint: BASE_STATES_CONTRACT_FINGERPRINT,\n phase: options.phase,\n userId: options.userId ?? \"test-user\",\n playerIds: literals.playerIds.slice(\n 0,\n BASE_STATES[options.baseId]?.fingerprint.players ?? literals.playerIds.length,\n ),\n });\n\n if (options.controllingPlayerId) {\n runtime.setControllingPlayer(options.controllingPlayerId);\n }\n\n return runtime;\n}\n`;\n\nexport function buildReducerTestingContractContent(\n options: {\n rejectionCodes?: readonly string[];\n } = {},\n): string {\n const rejectionCodes = Array.from(\n new Set([...(options.rejectionCodes ?? []), ...DEFAULT_REJECTION_CODES]),\n ).sort((left, right) => left.localeCompare(right));\n\n return `\\\n// Generated by dreamboard — do not edit by hand.\nimport type game from \"../../app/game\";\nimport { literals, type SetupProfileId } from \"../../shared/manifest-contract\";\nimport {\n type GameView,\n type InteractionId,\n type InteractionKey,\n type InteractionParamsOf,\n type PhaseName,\n type StageName as WorkspaceStageName,\n} from \"../../shared/generated/ui-contract\";\nimport type { ExpectFn as SharedExpectFn } from \"@dreamboard-games/sdk/testing\";\nimport type { InteractionDescriptor } from \"@dreamboard-games/sdk/runtime\";\nimport { BASE_STATES } from \"./base-states.generated\";\n\nexport type GameDefinition = typeof game;\nexport type PlayerId = (typeof literals.playerIds)[number];\nexport type StateName = PhaseName;\nexport type BaseId = keyof typeof BASE_STATES & string;\nexport type InteractionDescriptorFor<Id extends string = string> =\n InteractionDescriptor<Id>;\nexport type InteractionExplanation = {\n interactionId: string;\n phase: string;\n step: string | null;\n availability:\n | \"available\"\n | \"notYourTurn\"\n | \"wrongPhase\"\n | \"wrongStep\"\n | \"blocked\";\n rules: ReadonlyArray<{\n ruleId: string;\n outcome: \"passed\" | \"failed\" | \"notEvaluated\";\n errorCode?: string;\n message?: string;\n }>;\n actor: { required: readonly string[]; playerIsActor: boolean };\n inputs: ReadonlyArray<{\n key: string;\n kind: string;\n eligibleCount: number | \"lazy\";\n }>;\n};\nexport type ExpectFn = SharedExpectFn;\nexport type KnownRejectionCode = ${renderLiteralUnion(rejectionCodes)};\nexport type RejectionCode = [KnownRejectionCode] extends [never]\n ? string\n : KnownRejectionCode;\n\ntype PhaseTaggedView<Phase extends PhaseName> = Extract<\n GameView,\n { phase: Phase } | { currentPhase: Phase } | { state: Phase }\n>;\ntype NarrowedView<Phase extends PhaseName> = [PhaseTaggedView<Phase>] extends [never]\n ? GameView\n : PhaseTaggedView<Phase>;\n\nexport type ViewByPhase = {\n [Phase in PhaseName]: NarrowedView<Phase>;\n};\n\ntype InteractionKeyForId<Id extends InteractionId> = Extract<\n InteractionKey,\n \\`\\${string}.\\${Id}\\`\n>;\ntype InteractionParamsForKey<Key extends InteractionKey> =\n Key extends InteractionKey ? InteractionParamsOf<Key> : never;\ntype InteractionParamsOfId<Id extends InteractionId> =\n InteractionParamsForKey<InteractionKeyForId<Id>>;\n\nexport interface ScenarioGameApi {\n start(): Promise<void>;\n /**\n * Patch the reducer snapshot for deterministic setup-heavy scenarios.\n */\n patchState(mutator: (state: Record<string, unknown>) => void): Promise<void>;\n /**\n * Submit a player interaction (action-kind or prompt-kind) to the game.\n * The \\`interactionId\\` matches an \\`InteractionId\\` from the generated\n * \\`ui-contract\\`; \\`params\\` is typed per interaction id.\n */\n submit<Id extends InteractionId>(\n playerId: PlayerId,\n interactionId: Id,\n params?: InteractionParamsOfId<Id>,\n ): Promise<void>;\n}\n\nexport interface BaseContext {\n game: ScenarioGameApi;\n players(): readonly PlayerId[];\n /**\n * Resolve the seat at \\`index\\` in the base's players list.\n * Throws if the index is out of range. Prefer \\`seat(0)\\`/\\`seat(1)\\` over\n * literal player ids so bases stay portable across player counts and\n * we never hard-code wire-shape assumptions like \"player-1\".\n */\n seat(index: number): PlayerId;\n}\n\nexport interface SharedScenarioContext {\n game: ScenarioGameApi;\n players(): readonly PlayerId[];\n /**\n * Resolve the seat at \\`index\\` in the current scenario's players list.\n * Throws if the index is out of range. Prefer \\`seat(0)\\`/\\`seat(1)\\` over\n * literal player ids so scenarios stay portable across player counts and\n * we never hard-code wire-shape assumptions like \"player-1\".\n */\n seat(index: number): PlayerId;\n state(): StateName;\n view(playerId: PlayerId): GameView;\n interactions(playerId: PlayerId): readonly InteractionDescriptorFor[];\n explain(playerId: PlayerId, interactionId: InteractionId): InteractionExplanation;\n expect: ExpectFn;\n}\n\nexport type ScenarioContext<\n Phase extends PhaseName | undefined = undefined,\n> = Omit<SharedScenarioContext, \"state\" | \"view\"> & {\n state(): Phase extends PhaseName ? Phase : StateName;\n view(playerId: PlayerId): Phase extends PhaseName ? ViewByPhase[Phase] : GameView;\n};\n\nexport type ScenarioThenContext<\n Phase extends PhaseName | undefined = undefined,\n> = ScenarioContext<Phase>;\n\nexport interface BaseDefinition {\n id: string;\n seed?: number;\n players?: number;\n setupProfileId?: SetupProfileId;\n extends?: BaseId | string;\n setup: (ctx: BaseContext) => void | Promise<void>;\n}\n\nexport interface ScenarioDefinition<\n Phase extends PhaseName | undefined = undefined,\n> {\n id: string;\n description?: string;\n from: BaseId | string;\n phase?: Phase;\n stage?: Phase extends PhaseName ? WorkspaceStageName<Phase> : never;\n when: (ctx: ScenarioContext<Phase>) => void | Promise<void>;\n then: (ctx: ScenarioThenContext<Phase>) => void | Promise<void>;\n}\n\nexport type {\n GameView,\n InteractionId,\n InteractionParamsOf,\n PhaseName,\n WorkspaceStageName,\n};\n`;\n}\n"],"mappings":";;;AAAA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,mBAAmB,QAAmC;AAC7D,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AACA,SAAO,OAAO,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EAAE,KAAK,KAAK;AAChE;AAEO,IAAM,wCAAwC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+E9C,SAAS,mCACd,UAEI,CAAC,GACG;AACR,QAAM,iBAAiB,MAAM;AAAA,IAC3B,oBAAI,IAAI,CAAC,GAAI,QAAQ,kBAAkB,CAAC,GAAI,GAAG,uBAAuB,CAAC;AAAA,EACzE,EAAE,KAAK,CAAC,MAAM,UAAU,KAAK,cAAc,KAAK,CAAC;AAEjD,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCA8C0B,mBAAmB,cAAc,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiHrE;","names":[]}
@@ -4,10 +4,10 @@ import {
4
4
  getGlobalConfigPath,
5
5
  loadGlobalConfig,
6
6
  saveGlobalConfig
7
- } from "./chunk-5NYBTZB4.mjs";
8
- import "./chunk-TAEQKBJB.mjs";
9
- import "./chunk-IAYRNVUC.mjs";
10
- import "./chunk-H76MT5UR.mjs";
7
+ } from "./chunk-MIRGCMUC.mjs";
8
+ import "./chunk-GWRZRWCF.mjs";
9
+ import "./chunk-LMW66VBH.mjs";
10
+ import "./chunk-M7UVBANQ.mjs";
11
11
  import "./chunk-H6XDQJ3N.mjs";
12
12
  export {
13
13
  getGlobalAuthPath,
@@ -15,4 +15,4 @@ export {
15
15
  loadGlobalConfig,
16
16
  saveGlobalConfig
17
17
  };
18
- //# sourceMappingURL=global-config-NYCSCAUI.mjs.map
18
+ //# sourceMappingURL=global-config-2NUESNEQ.mjs.map
@@ -29,11 +29,14 @@ function parsePayload(raw) {
29
29
  if (trimmed.length === 0) return null;
30
30
  try {
31
31
  const parsed = JSON.parse(trimmed);
32
- if (!parsed.accessToken && !parsed.refreshToken) return null;
32
+ const accessToken = parsed.clerkAccessToken ?? parsed.accessToken;
33
+ if (!accessToken && !parsed.refreshToken) return null;
33
34
  return {
34
- accessToken: parsed.accessToken || void 0,
35
+ accessToken: accessToken || void 0,
35
36
  refreshToken: parsed.refreshToken || void 0,
36
- tokenExpiresAt: parsed.tokenExpiresAt || void 0,
37
+ tokenExpiresAt: parsed.clerkAccessExpiresAt || parsed.tokenExpiresAt || void 0,
38
+ dreamboardApiToken: parsed.dreamboardApiToken || void 0,
39
+ dreamboardApiExpiresAt: parsed.dreamboardApiExpiresAt || void 0,
37
40
  clerkOAuthIssuer: parsed.clerkOAuthIssuer || void 0,
38
41
  clerkOAuthClientId: parsed.clerkOAuthClientId || void 0,
39
42
  clerkOAuthTokenUrl: parsed.clerkOAuthTokenUrl || void 0,
@@ -50,9 +53,11 @@ function writeFull(entry, creds) {
50
53
  );
51
54
  }
52
55
  const payload = {
53
- accessToken: creds.accessToken,
56
+ clerkAccessToken: creds.accessToken,
54
57
  refreshToken: creds.refreshToken,
55
- tokenExpiresAt: creds.tokenExpiresAt,
58
+ clerkAccessExpiresAt: creds.tokenExpiresAt,
59
+ dreamboardApiToken: creds.dreamboardApiToken,
60
+ dreamboardApiExpiresAt: creds.dreamboardApiExpiresAt,
56
61
  clerkOAuthIssuer: creds.clerkOAuthIssuer,
57
62
  clerkOAuthClientId: creds.clerkOAuthClientId,
58
63
  clerkOAuthTokenUrl: creds.clerkOAuthTokenUrl,
@@ -132,4 +137,4 @@ export {
132
137
  _setKeyringModuleForTests,
133
138
  tryKeychainBackend
134
139
  };
135
- //# sourceMappingURL=keychain-backend-A3MRWLPF.mjs.map
140
+ //# sourceMappingURL=keychain-backend-FF4I6ODB.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/keychain-backend.ts"],"sourcesContent":["/**\n * OS keychain-backed `CredentialBackend` built on top of `@napi-rs/keyring`.\n *\n * Keychain is an optional storage backend. Users can opt in with\n * `credentialBackend: \"keychain\"` in `~/.dreamboard/config.json`\n * (see `credential-store.ts` for the resolver).\n * When enabled, it gives us:\n * - A refresh token encrypted at rest by the OS (Keychain on macOS,\n * Credential Vault on Windows, Secret Service on Linux).\n * - Protection against other processes running as the same user tailing\n * `~/.dreamboard/auth.json` to scrape the token.\n *\n * This module is loaded optionally: `@napi-rs/keyring` is declared as an\n * `optionalDependencies` entry. If the native binary or OS keyring is\n * unavailable, the resolver falls back to the file backend.\n *\n * One-time migration: when the active backend is keychain and `auth.json` still\n * has tokens, `credential-store.ts` copies them into the keychain, verifies the\n * keychain read, and deletes the file. This is the only path that intentionally\n * mutates both backends.\n */\n\nimport type {\n CredentialBackend,\n Credentials,\n StoredSessionSnapshot,\n} from \"./credential-store.js\";\n\n/** Keychain service id. Shared across all Dreamboard CLI builds. */\nconst KEYCHAIN_SERVICE = \"dreamboard-cli\";\n/**\n * Keychain account id. The `user@host` shape is conventional but we keep\n * it fixed for now because the CLI only cares about \"the session for this\n * OS user\", not per-process sessions.\n */\nconst KEYCHAIN_ACCOUNT = \"session\";\n\ntype EntryInstance = {\n setPassword(value: string): void;\n getPassword(): string | null | undefined;\n deletePassword(): boolean;\n};\n\ntype KeyringModule = {\n Entry: new (service: string, account: string) => EntryInstance;\n};\n\nlet cachedModule: KeyringModule | null | undefined;\n\nasync function loadKeyringModule(): Promise<KeyringModule | null> {\n if (cachedModule !== undefined) return cachedModule;\n try {\n // `@napi-rs/keyring` is an optional dependency. If the native binary is\n // missing on this platform the dynamic import throws; resolver policy in\n // credential-store decides whether that is fatal.\n const mod = (await import(\"@napi-rs/keyring\")) as unknown as KeyringModule;\n cachedModule = mod;\n } catch {\n cachedModule = null;\n }\n return cachedModule;\n}\n\nfunction keychainProbe(entry: EntryInstance): boolean {\n // Some platforms have the module installed but no accessible keyring\n // (e.g. headless Linux without DBus). Touch getPassword to verify we\n // can talk to the service without side effects.\n try {\n entry.getPassword();\n return true;\n } catch {\n return false;\n }\n}\n\ntype KeychainPayload = {\n clerkAccessToken?: string;\n accessToken?: string;\n refreshToken?: string;\n clerkAccessExpiresAt?: string;\n tokenExpiresAt?: string;\n dreamboardApiToken?: string;\n dreamboardApiExpiresAt?: string;\n clerkOAuthIssuer?: string;\n clerkOAuthClientId?: string;\n clerkOAuthTokenUrl?: string;\n environment?: string;\n};\n\nfunction parsePayload(\n raw: string | null | undefined,\n): StoredSessionSnapshot | null {\n if (raw === null || raw === undefined) return null;\n const trimmed = raw.trim();\n if (trimmed.length === 0) return null;\n try {\n const parsed = JSON.parse(trimmed) as KeychainPayload;\n const accessToken = parsed.clerkAccessToken ?? parsed.accessToken;\n if (!accessToken && !parsed.refreshToken) return null;\n return {\n accessToken: accessToken || undefined,\n refreshToken: parsed.refreshToken || undefined,\n tokenExpiresAt:\n parsed.clerkAccessExpiresAt || parsed.tokenExpiresAt || undefined,\n dreamboardApiToken: parsed.dreamboardApiToken || undefined,\n dreamboardApiExpiresAt: parsed.dreamboardApiExpiresAt || undefined,\n clerkOAuthIssuer: parsed.clerkOAuthIssuer || undefined,\n clerkOAuthClientId: parsed.clerkOAuthClientId || undefined,\n clerkOAuthTokenUrl: parsed.clerkOAuthTokenUrl || undefined,\n environment: parsed.environment || undefined,\n };\n } catch {\n return null;\n }\n}\n\nfunction writeFull(entry: EntryInstance, creds: Credentials): void {\n if (!creds.accessToken || !creds.refreshToken) {\n throw new Error(\n \"Refusing to persist credentials with an empty accessToken or refreshToken.\",\n );\n }\n const payload: KeychainPayload = {\n clerkAccessToken: creds.accessToken,\n refreshToken: creds.refreshToken,\n clerkAccessExpiresAt: creds.tokenExpiresAt,\n dreamboardApiToken: creds.dreamboardApiToken,\n dreamboardApiExpiresAt: creds.dreamboardApiExpiresAt,\n clerkOAuthIssuer: creds.clerkOAuthIssuer,\n clerkOAuthClientId: creds.clerkOAuthClientId,\n clerkOAuthTokenUrl: creds.clerkOAuthTokenUrl,\n environment: creds.environment,\n };\n entry.setPassword(JSON.stringify(payload));\n}\n\nfunction writeAccessOnly(entry: EntryInstance, accessToken: string): void {\n if (!accessToken) {\n throw new Error(\"Refusing to persist an empty access token.\");\n }\n const payload: KeychainPayload = { accessToken };\n entry.setPassword(JSON.stringify(payload));\n}\n\nfunction clear(entry: EntryInstance): void {\n try {\n entry.deletePassword();\n } catch {\n // keyring-rs throws when the entry does not exist. That is fine -\n // Session clearing is idempotent.\n }\n}\n\nexport type KeychainAvailability =\n | { available: true; backend: CredentialBackend }\n | { available: false; reason: string };\n\n/**\n * Attempt to construct a keychain-backed `CredentialBackend`. Returns an\n * `available: false` result (with a reason) if the native module, the\n * OS keyring, or the probe fails.\n */\nexport async function tryKeychainBackend(): Promise<KeychainAvailability> {\n const mod = await loadKeyringModule();\n if (!mod) {\n return {\n available: false,\n reason: \"@napi-rs/keyring is not installed for this platform\",\n };\n }\n\n let entry: EntryInstance;\n try {\n entry = new mod.Entry(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT);\n } catch (err) {\n return {\n available: false,\n reason: `Failed to construct keyring entry: ${String((err as Error).message ?? err)}`,\n };\n }\n\n if (!keychainProbe(entry)) {\n return {\n available: false,\n reason: \"OS keyring is not accessible from this process\",\n };\n }\n\n const backend: CredentialBackend = {\n name: \"keychain\",\n async read() {\n try {\n return parsePayload(entry.getPassword());\n } catch (err) {\n const message = String((err as Error).message ?? err);\n // Transient keychain access errors (e.g. Touch ID prompt\n // cancelled) should not surface as \"session wiped\". Treat the\n // unreadable state as \"no session\" so the caller can fall back\n // to prompting for login.\n if (/no matching entry|not found/i.test(message)) {\n return null;\n }\n throw err;\n }\n },\n async writeFull(creds) {\n writeFull(entry, creds);\n },\n async writeAccessOnly(accessToken) {\n writeAccessOnly(entry, accessToken);\n },\n async clear() {\n clear(entry);\n },\n };\n return { available: true, backend };\n}\n\n/**\n * Test-only escape hatch so unit tests can install a fake keyring module\n * without going through the dynamic import cache.\n */\nexport function _setKeyringModuleForTests(mod: KeyringModule | null): void {\n cachedModule = mod;\n}\n\nexport function _resetKeyringModuleForTests(): void {\n cachedModule = undefined;\n}\n"],"mappings":"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","names":[]}
@@ -14,16 +14,16 @@ import {
14
14
  writeSnapshot,
15
15
  writeSnapshotFromFiles,
16
16
  writeSourceFiles
17
- } from "./chunk-27EEIZCI.mjs";
17
+ } from "./chunk-KDAQ4CZY.mjs";
18
+ import "./chunk-GWRZRWCF.mjs";
18
19
  import {
19
20
  computeManifestHash
20
- } from "./chunk-C3VW3DTA.mjs";
21
+ } from "./chunk-BWBN2TDJ.mjs";
21
22
  import "./chunk-JZTH3EMV.mjs";
22
- import "./chunk-QBAF7EYR.mjs";
23
- import "./chunk-NAK77WXW.mjs";
24
- import "./chunk-TAEQKBJB.mjs";
25
- import "./chunk-IAYRNVUC.mjs";
26
- import "./chunk-H76MT5UR.mjs";
23
+ import "./chunk-TTB7AIHZ.mjs";
24
+ import "./chunk-MYMVXTZT.mjs";
25
+ import "./chunk-OJFZVGEL.mjs";
26
+ import "./chunk-M7UVBANQ.mjs";
27
27
  import "./chunk-H6XDQJ3N.mjs";
28
28
  export {
29
29
  collectLocalFiles,
@@ -42,4 +42,4 @@ export {
42
42
  writeSnapshotFromFiles,
43
43
  writeSourceFiles
44
44
  };
45
- //# sourceMappingURL=local-files-QVJ2H3MH.mjs.map
45
+ //# sourceMappingURL=local-files-OF4QFISU.mjs.map
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  MANIFEST_TYPECHECK_CONFIG_FILE
4
- } from "./chunk-H76MT5UR.mjs";
4
+ } from "./chunk-M7UVBANQ.mjs";
5
+ import "./chunk-H6XDQJ3N.mjs";
5
6
 
6
7
  // src/services/project/local-typecheck.ts
7
8
  import { spawn } from "child_process";
@@ -41,7 +42,7 @@ async function ensureTypecheckDependencies(projectRoot) {
41
42
  if (await pathExists(getProjectNodeModules(projectRoot))) {
42
43
  return null;
43
44
  }
44
- return `Skipping local typecheck: workspace dependencies are not installed at ${getProjectNodeModules(projectRoot)}. Run \`dreamboard sync\` to reconcile workspace dependencies first.`;
45
+ return `Skipping local typecheck: workspace dependencies are not installed at ${getProjectNodeModules(projectRoot)}. Run \`pnpm install --frozen-lockfile\` or recreate the workspace with \`dreamboard project create\` / \`dreamboard project clone\` first.`;
45
46
  }
46
47
  async function resolveTypecheckRunner(projectRoot) {
47
48
  const localTypescriptCli = getProjectTypescriptCli(projectRoot);
@@ -143,8 +144,7 @@ async function runLocalTypecheck(projectRoot) {
143
144
  output: ""
144
145
  };
145
146
  }
146
-
147
147
  export {
148
148
  runLocalTypecheck
149
149
  };
150
- //# sourceMappingURL=chunk-UIOLGH4A.mjs.map
150
+ //# sourceMappingURL=local-typecheck-DHVLM37Z.mjs.map
@@ -0,0 +1 @@
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 \\`pnpm install --frozen-lockfile\\` or recreate the workspace with \\`dreamboard project create\\` / \\`dreamboard project clone\\` 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"]}
@@ -3,34 +3,35 @@ import {
3
3
  updateProjectAuthoringState,
4
4
  updateProjectLocalMaintainerRegistry
5
5
  } from "./chunk-YE7UAO3T.mjs";
6
+ import {
7
+ updateProjectState
8
+ } from "./chunk-LROY5SN2.mjs";
6
9
  import {
7
10
  writeManifest,
8
11
  writeRule,
9
12
  writeSnapshot
10
- } from "./chunk-27EEIZCI.mjs";
13
+ } from "./chunk-KDAQ4CZY.mjs";
14
+ import "./chunk-GWRZRWCF.mjs";
11
15
  import {
12
16
  scaffoldStaticWorkspace
13
- } from "./chunk-MW2QIWWA.mjs";
14
- import "./chunk-F2DIOJJZ.mjs";
17
+ } from "./chunk-KAA3B4DI.mjs";
18
+ import "./chunk-XCQQIPCO.mjs";
15
19
  import {
16
- updateProjectState
17
- } from "./chunk-776W3UGV.mjs";
18
- import "./chunk-C3VW3DTA.mjs";
20
+ ensureDir
21
+ } from "./chunk-LMW66VBH.mjs";
22
+ import "./chunk-BWBN2TDJ.mjs";
19
23
  import "./chunk-JZTH3EMV.mjs";
20
- import "./chunk-QBAF7EYR.mjs";
21
- import "./chunk-NAK77WXW.mjs";
22
- import "./chunk-TAEQKBJB.mjs";
24
+ import "./chunk-TTB7AIHZ.mjs";
25
+ import "./chunk-MYMVXTZT.mjs";
23
26
  import {
24
27
  applyWorkspaceCodegen
25
- } from "./chunk-G42BGGG2.mjs";
26
- import {
27
- ensureDir
28
- } from "./chunk-IAYRNVUC.mjs";
28
+ } from "./chunk-HUBV22JQ.mjs";
29
+ import "./chunk-OJFZVGEL.mjs";
29
30
  import {
30
31
  installWorkspaceDependencies
31
- } from "./chunk-XQXDOBYB.mjs";
32
+ } from "./chunk-4I2WWAPK.mjs";
32
33
  import "./chunk-ZEELHSY3.mjs";
33
- import "./chunk-H76MT5UR.mjs";
34
+ import "./chunk-M7UVBANQ.mjs";
34
35
  import "./chunk-H6XDQJ3N.mjs";
35
36
 
36
37
  // src/services/project/materialize-workspace.ts
@@ -43,12 +44,12 @@ async function materializeWorkspaceProject(input) {
43
44
  await scaffoldStaticWorkspace(targetDir, "new", {
44
45
  localMaintainerRegistry: input.localMaintainerRegistry
45
46
  });
46
- await applyWorkspaceCodegen({
47
- projectRoot: targetDir,
48
- manifest: input.manifest
49
- });
50
47
  if (input.installDependencies ?? true) {
51
48
  await installWorkspaceDependencies(targetDir);
49
+ await applyWorkspaceCodegen({
50
+ projectRoot: targetDir,
51
+ manifest: input.manifest
52
+ });
52
53
  }
53
54
  const authoringConfig = input.ruleId && input.manifestId && input.manifestContentHash ? updateProjectAuthoringState(baseProjectConfig(input), {
54
55
  ruleId: input.ruleId,
@@ -66,8 +67,7 @@ async function materializeWorkspaceProject(input) {
66
67
  function baseProjectConfig(input) {
67
68
  return {
68
69
  schemaVersion: 2,
69
- projectId: input.projectId ?? input.gameId,
70
- gameId: input.gameId,
70
+ projectId: input.projectId,
71
71
  deploymentId: input.deploymentId ?? "legacy",
72
72
  ownerScopeId: input.ownerScopeId ?? "default",
73
73
  bindingKey: input.bindingKey,
@@ -86,4 +86,4 @@ function baseProjectConfig(input) {
86
86
  export {
87
87
  materializeWorkspaceProject
88
88
  };
89
- //# sourceMappingURL=materialize-workspace-OZKOQCSQ.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":[]}