@dreamboard-games/cli 0.1.30-alpha.19 → 0.1.30-alpha.20

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 (97) hide show
  1. package/README.md +22 -102
  2. package/dist/agent-verifier/agent-workspace-verifier.mjs +1508 -55
  3. package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -1
  4. package/dist/agent-verifier/{chunk-V7ABTZXW.mjs → chunk-4I2WWAPK.mjs} +26 -7
  5. package/dist/agent-verifier/chunk-4I2WWAPK.mjs.map +1 -0
  6. package/dist/agent-verifier/{chunk-7LFDFXLS.mjs → chunk-BWBN2TDJ.mjs} +338 -133
  7. package/dist/agent-verifier/chunk-BWBN2TDJ.mjs.map +1 -0
  8. package/dist/agent-verifier/{chunk-AWZ4M4NS.mjs → chunk-DQUYBIGQ.mjs} +5 -6
  9. package/dist/agent-verifier/chunk-DQUYBIGQ.mjs.map +1 -0
  10. package/dist/agent-verifier/{chunk-H5L4KK4Y.mjs → chunk-GCFGAFYC.mjs} +7 -7
  11. package/dist/agent-verifier/chunk-GCFGAFYC.mjs.map +1 -0
  12. package/dist/agent-verifier/{chunk-TAEQKBJB.mjs → chunk-GWRZRWCF.mjs} +1 -1
  13. package/dist/agent-verifier/chunk-GWRZRWCF.mjs.map +1 -0
  14. package/dist/agent-verifier/{chunk-6AKXIY37.mjs → chunk-IWB4L2HV.mjs} +3 -3
  15. package/dist/agent-verifier/chunk-IWB4L2HV.mjs.map +1 -0
  16. package/dist/agent-verifier/{chunk-334H4LE4.mjs → chunk-KDAQ4CZY.mjs} +3 -3
  17. package/dist/agent-verifier/{chunk-WSIYUUSD.mjs → chunk-TIDX3YLW.mjs} +2 -2
  18. package/dist/agent-verifier/{chunk-WSIYUUSD.mjs.map → chunk-TIDX3YLW.mjs.map} +1 -1
  19. package/dist/agent-verifier/{chunk-UMW24KZI.mjs → chunk-UXGTT25Q.mjs} +3 -3
  20. package/dist/agent-verifier/{global-config-SXR6X3OZ.mjs → global-config-IXZLY4BS.mjs} +4 -4
  21. package/dist/agent-verifier/{local-files-DAFIR7SN.mjs → local-files-OF4QFISU.mjs} +4 -4
  22. package/dist/agent-verifier/{chunk-POBFNXD4.mjs → local-typecheck-DHVLM37Z.mjs} +3 -3
  23. package/dist/agent-verifier/local-typecheck-DHVLM37Z.mjs.map +1 -0
  24. package/dist/agent-verifier/{materialize-workspace-PWNT6HQK.mjs → materialize-workspace-VS5RHSBO.mjs} +7 -7
  25. package/dist/agent-verifier/{chunk-HLHT57AW.mjs → reducer-bundle-preflight-GLUJKTWU.mjs} +13 -10
  26. package/dist/agent-verifier/reducer-bundle-preflight-GLUJKTWU.mjs.map +1 -0
  27. package/dist/agent-verifier/{chunk-INIK6LHK.mjs → reducer-contract-preflight-WVQQPW5F.mjs} +6 -5
  28. package/dist/agent-verifier/reducer-contract-preflight-WVQQPW5F.mjs.map +1 -0
  29. package/dist/agent-verifier/{chunk-3Y4FRMTK.mjs → reducer-native-test-harness-H6G6RBRY.mjs} +150 -34
  30. package/dist/agent-verifier/reducer-native-test-harness-H6G6RBRY.mjs.map +1 -0
  31. package/dist/agent-verifier/{static-scaffold-HXUQLJVN.mjs → static-scaffold-C36KROJA.mjs} +3 -3
  32. package/dist/agent-verifier/{workspace-dependencies-ZMHPHVQV.mjs → workspace-dependencies-5HEEKZFP.mjs} +4 -2
  33. package/dist/authoring-compatibility-internal.js +2 -2
  34. package/dist/{chunk-R6RB4EKH.js → chunk-5PJWUB6W.js} +179 -210
  35. package/dist/chunk-5PJWUB6W.js.map +1 -0
  36. package/dist/{chunk-YRSE5DLH.js → chunk-EJGB3IR7.js} +422 -264
  37. package/dist/chunk-EJGB3IR7.js.map +1 -0
  38. package/dist/{chunk-FFO2IJL3.js → chunk-EQNBQVIW.js} +1 -1
  39. package/dist/chunk-EQNBQVIW.js.map +1 -0
  40. package/dist/{chunk-VWMKJL4A.js → chunk-UI7NWSYA.js} +3 -3
  41. package/dist/chunk-UI7NWSYA.js.map +1 -0
  42. package/dist/{global-config-UHGWFJIK.js → global-config-GK2UC2X6.js} +3 -3
  43. package/dist/index.js +2691 -3953
  44. package/dist/index.js.map +1 -1
  45. package/dist/internal.js +4 -4
  46. package/package.json +1 -1
  47. package/release/authoring-release-set.json +2 -2
  48. package/skills/dreamboard/SKILL.md +30 -28
  49. package/skills/dreamboard/references/building-your-first-game.md +15 -15
  50. package/skills/dreamboard/references/cli.md +48 -47
  51. package/skills/dreamboard/references/quickstart.md +16 -13
  52. package/skills/dreamboard/references/testing.md +10 -10
  53. package/dist/agent-verifier/chunk-3Y4FRMTK.mjs.map +0 -1
  54. package/dist/agent-verifier/chunk-5D3OJBDT.mjs +0 -1547
  55. package/dist/agent-verifier/chunk-5D3OJBDT.mjs.map +0 -1
  56. package/dist/agent-verifier/chunk-6AKXIY37.mjs.map +0 -1
  57. package/dist/agent-verifier/chunk-7LFDFXLS.mjs.map +0 -1
  58. package/dist/agent-verifier/chunk-AWZ4M4NS.mjs.map +0 -1
  59. package/dist/agent-verifier/chunk-H5L4KK4Y.mjs.map +0 -1
  60. package/dist/agent-verifier/chunk-HLHT57AW.mjs.map +0 -1
  61. package/dist/agent-verifier/chunk-INIK6LHK.mjs.map +0 -1
  62. package/dist/agent-verifier/chunk-LEWM26XR.mjs +0 -618
  63. package/dist/agent-verifier/chunk-LEWM26XR.mjs.map +0 -1
  64. package/dist/agent-verifier/chunk-PLXXH5LY.mjs +0 -222
  65. package/dist/agent-verifier/chunk-PLXXH5LY.mjs.map +0 -1
  66. package/dist/agent-verifier/chunk-POBFNXD4.mjs.map +0 -1
  67. package/dist/agent-verifier/chunk-TAEQKBJB.mjs.map +0 -1
  68. package/dist/agent-verifier/chunk-V7ABTZXW.mjs.map +0 -1
  69. package/dist/agent-verifier/chunk-ZOR5FTIG.mjs +0 -39
  70. package/dist/agent-verifier/chunk-ZOR5FTIG.mjs.map +0 -1
  71. package/dist/agent-verifier/compile-MO2URO5Z.mjs +0 -317
  72. package/dist/agent-verifier/compile-MO2URO5Z.mjs.map +0 -1
  73. package/dist/agent-verifier/local-typecheck-3JXL2NMG.mjs +0 -10
  74. package/dist/agent-verifier/reducer-bundle-preflight-3DSXIELT.mjs +0 -20
  75. package/dist/agent-verifier/reducer-contract-preflight-FQB7M4PU.mjs +0 -11
  76. package/dist/agent-verifier/reducer-native-test-harness-X2KQYSCD.mjs +0 -53
  77. package/dist/agent-verifier/reducer-native-test-harness-X2KQYSCD.mjs.map +0 -1
  78. package/dist/agent-verifier/static-scaffold-HXUQLJVN.mjs.map +0 -1
  79. package/dist/agent-verifier/sync-5YM4CSXL.mjs +0 -598
  80. package/dist/agent-verifier/sync-5YM4CSXL.mjs.map +0 -1
  81. package/dist/agent-verifier/test-CNNVTFIG.mjs +0 -356
  82. package/dist/agent-verifier/test-CNNVTFIG.mjs.map +0 -1
  83. package/dist/agent-verifier/workspace-dependencies-ZMHPHVQV.mjs.map +0 -1
  84. package/dist/chunk-FFO2IJL3.js.map +0 -1
  85. package/dist/chunk-R6RB4EKH.js.map +0 -1
  86. package/dist/chunk-VWMKJL4A.js.map +0 -1
  87. package/dist/chunk-YRSE5DLH.js.map +0 -1
  88. package/dist/global-config-UHGWFJIK.js.map +0 -1
  89. package/skills/dreamboard/scripts/events-extract.mjs +0 -218
  90. /package/dist/agent-verifier/{chunk-334H4LE4.mjs.map → chunk-KDAQ4CZY.mjs.map} +0 -0
  91. /package/dist/agent-verifier/{chunk-UMW24KZI.mjs.map → chunk-UXGTT25Q.mjs.map} +0 -0
  92. /package/dist/agent-verifier/{global-config-SXR6X3OZ.mjs.map → global-config-IXZLY4BS.mjs.map} +0 -0
  93. /package/dist/agent-verifier/{local-files-DAFIR7SN.mjs.map → local-files-OF4QFISU.mjs.map} +0 -0
  94. /package/dist/agent-verifier/{materialize-workspace-PWNT6HQK.mjs.map → materialize-workspace-VS5RHSBO.mjs.map} +0 -0
  95. /package/dist/agent-verifier/{local-typecheck-3JXL2NMG.mjs.map → static-scaffold-C36KROJA.mjs.map} +0 -0
  96. /package/dist/agent-verifier/{reducer-bundle-preflight-3DSXIELT.mjs.map → workspace-dependencies-5HEEKZFP.mjs.map} +0 -0
  97. /package/dist/{agent-verifier/reducer-contract-preflight-FQB7M4PU.mjs.map → global-config-GK2UC2X6.js.map} +0 -0
@@ -18,7 +18,6 @@ import {
18
18
  listProjectCompiledResults,
19
19
  loadManifest,
20
20
  loadProjectConfig,
21
- queueProjectRevisionCompile,
22
21
  readWorkspaceTextFileIfExists,
23
22
  resolveCliRepoRoot,
24
23
  resolveWorkspacePath,
@@ -27,14 +26,14 @@ import {
27
26
  writeWorkspaceJsonFile,
28
27
  writeWorkspaceTextFile,
29
28
  zProblemDetails
30
- } from "./chunk-YRSE5DLH.js";
29
+ } from "./chunk-EJGB3IR7.js";
31
30
  import {
32
31
  clearCredentials,
33
32
  getStoredSession,
34
33
  loadGlobalConfig,
35
34
  setCredentials,
36
35
  withCredentialLock
37
- } from "./chunk-VWMKJL4A.js";
36
+ } from "./chunk-UI7NWSYA.js";
38
37
  import {
39
38
  DEFAULT_API_BASE_URL,
40
39
  DEFAULT_WEB_BASE_URL,
@@ -42,9 +41,8 @@ import {
42
41
  PROJECT_DIR_NAME,
43
42
  ensureDir,
44
43
  exists,
45
- readJsonFile,
46
44
  writeJsonFile
47
- } from "./chunk-FFO2IJL3.js";
45
+ } from "./chunk-EQNBQVIW.js";
48
46
 
49
47
  // src/build-target.ts
50
48
  var injectedBuildChannel = true ? "published" : void 0;
@@ -167,7 +165,7 @@ async function exchangeDreamboardUserToken(input) {
167
165
  );
168
166
  if (!response.ok) {
169
167
  throw new Error(
170
- `Dreamboard token exchange failed (${response.status}). Run \`dreamboard login\` to authenticate again.`
168
+ `Dreamboard token exchange failed (${response.status}). Run \`dreamboard auth login\` to authenticate again.`
171
169
  );
172
170
  }
173
171
  const payload = await response.json();
@@ -227,7 +225,7 @@ function createUserTokenManager(config) {
227
225
  if (localOrInjected) return localOrInjected;
228
226
  if (!usesStoredSession(config)) {
229
227
  throw new Error(
230
- "Missing Dreamboard session. Run `dreamboard login` to authenticate."
228
+ "Missing Dreamboard session. Run `dreamboard auth login` to authenticate."
231
229
  );
232
230
  }
233
231
  return withCredentialLock(async (ops) => {
@@ -277,7 +275,7 @@ async function resolveFreshClerkAccessToken(config, stored) {
277
275
  const tokenExpiresAt = stored?.tokenExpiresAt ?? config.clerkAccessExpiresAt;
278
276
  if (!refreshToken) {
279
277
  throw new Error(
280
- "Stored Dreamboard session is missing its refresh token. Run `dreamboard login` to authenticate again."
278
+ "Stored Dreamboard session is missing its refresh token. Run `dreamboard auth login` to authenticate again."
281
279
  );
282
280
  }
283
281
  if (accessToken && isFresh(tokenExpiresAt, accessToken)) {
@@ -548,12 +546,12 @@ function assertPublicRuntimeFlags(flags) {
548
546
  }
549
547
  if (valueOrUndefined(flags.token) || argv.includes("--token")) {
550
548
  throw new Error(
551
- "Direct JWT injection is not supported in the published Dreamboard CLI. Use `dreamboard login` so the CLI can store and refresh your session."
549
+ "Direct JWT injection is not supported in the published Dreamboard CLI. Use `dreamboard auth login` so the CLI can store and refresh your session."
552
550
  );
553
551
  }
554
552
  if (process.env.DREAMBOARD_TOKEN) {
555
553
  throw new Error(
556
- "The published Dreamboard CLI ignores direct token environment variables. Use `dreamboard login` so the CLI can manage refreshable credentials."
554
+ "The published Dreamboard CLI ignores direct token environment variables. Use `dreamboard auth login` so the CLI can manage refreshable credentials."
557
555
  );
558
556
  }
559
557
  }
@@ -632,7 +630,7 @@ async function refreshClerkOAuthSession(config) {
632
630
  function requireAuth(config) {
633
631
  if (!config.authToken && !config.refreshToken && !resolveLocalHarnessAccessToken(config)) {
634
632
  throw new Error(
635
- "Missing Dreamboard session. Run `dreamboard login` to authenticate."
633
+ "Missing Dreamboard session. Run `dreamboard auth login` to authenticate."
636
634
  );
637
635
  }
638
636
  }
@@ -698,10 +696,14 @@ var playerCountFlagsSchema = external_exports.object({
698
696
  var newCommandArgsSchema = configFlagsSchema.extend({
699
697
  slug: external_exports.string().min(1),
700
698
  description: external_exports.string().min(1),
701
- force: external_exports.boolean().default(false)
699
+ force: external_exports.boolean().default(false),
700
+ "wait-timeout-ms": external_exports.string().optional(),
701
+ "repository-poll-interval-ms": external_exports.string().optional()
702
702
  });
703
703
  var cloneCommandArgsSchema = configFlagsSchema.extend({
704
- slug: external_exports.string().min(1)
704
+ slug: external_exports.string().min(1),
705
+ "wait-timeout-ms": external_exports.string().optional(),
706
+ "repository-poll-interval-ms": external_exports.string().optional()
705
707
  });
706
708
  var queryCommandArgsSchema = configFlagsSchema.extend({
707
709
  title: external_exports.string().min(1)
@@ -720,6 +722,16 @@ var compileCommandArgsSchema = configFlagsSchema.extend({
720
722
  var statusCommandArgsSchema = configFlagsSchema.extend({
721
723
  json: external_exports.boolean().default(false)
722
724
  });
725
+ var commitScopedCommandArgsSchema = configFlagsSchema.extend({
726
+ commit: external_exports.string().min(1),
727
+ json: external_exports.boolean().default(false)
728
+ });
729
+ var buildCommandArgsSchema = commitScopedCommandArgsSchema.extend({
730
+ profile: external_exports.enum(["preview", "release"]).optional().default("preview")
731
+ });
732
+ var releasePublishCommandArgsSchema = commitScopedCommandArgsSchema.extend({
733
+ yes: external_exports.boolean().default(false)
734
+ });
723
735
  var devCommandArgsSchema = configFlagsSchema.extend({
724
736
  seed: external_exports.string().optional(),
725
737
  "setup-profile": external_exports.string().optional(),
@@ -739,13 +751,19 @@ var joinCommandArgsSchema = configFlagsSchema.extend({
739
751
  player: external_exports.string().min(1),
740
752
  "raw-events": external_exports.boolean().default(false)
741
753
  });
742
- var loginCommandArgsSchema = configFlagsSchema;
743
754
  var configCommandArgsSchema = configFlagsSchema.extend({
744
755
  action: external_exports.string().optional().default("show"),
745
756
  scope: external_exports.enum(["global", "workspace"]).optional().default("global")
746
757
  });
747
758
  var authCommandArgsSchema = external_exports.object({
748
- action: external_exports.enum(["set", "clear", "login", "env", "status", "git-credential"]),
759
+ action: external_exports.enum([
760
+ "set",
761
+ "login",
762
+ "logout",
763
+ "env",
764
+ "status",
765
+ "git-credential"
766
+ ]),
749
767
  tokenValue: external_exports.string().optional(),
750
768
  token: external_exports.string().optional(),
751
769
  jwt: external_exports.boolean().optional(),
@@ -774,33 +792,18 @@ function parseNewCommandArgs(args) {
774
792
  function parseCloneCommandArgs(args) {
775
793
  return parseArgs("clone", cloneCommandArgsSchema, args);
776
794
  }
777
- function parseQueryCommandArgs(args) {
778
- return parseArgs("query", queryCommandArgsSchema, args);
779
- }
780
- function parsePullCommandArgs(args) {
781
- return parseArgs("pull", pullCommandArgsSchema, args);
795
+ function parseCommitScopedCommandArgs(commandName, args) {
796
+ return parseArgs(commandName, commitScopedCommandArgsSchema, args);
782
797
  }
783
- function parseSyncCommandArgs(args) {
784
- return parseArgs("sync", syncCommandArgsSchema, args);
798
+ function parseBuildCommandArgs(args) {
799
+ return parseArgs("build", buildCommandArgsSchema, args);
785
800
  }
786
- function parseCompileCommandArgs(args) {
787
- return parseArgs("compile", compileCommandArgsSchema, args);
788
- }
789
- function parseStatusCommandArgs(args) {
790
- return parseArgs("status", statusCommandArgsSchema, args);
801
+ function parseReleasePublishCommandArgs(args) {
802
+ return parseArgs("release publish", releasePublishCommandArgsSchema, args);
791
803
  }
792
804
  function parseDevCommandArgs(args) {
793
805
  return parseArgs("dev", devCommandArgsSchema, args);
794
806
  }
795
- function parseJoinCommandArgs(args) {
796
- return parseArgs("join", joinCommandArgsSchema, args);
797
- }
798
- function parseLoginCommandArgs(args) {
799
- return parseArgs("login", loginCommandArgsSchema, args);
800
- }
801
- function parseConfigCommandArgs(args) {
802
- return parseArgs("config", configCommandArgsSchema, args);
803
- }
804
807
  function parseAuthCommandArgs(args) {
805
808
  return parseArgs("auth", authCommandArgsSchema, args);
806
809
  }
@@ -943,15 +946,15 @@ function isGameNotFoundProblem(problem) {
943
946
  function getProblemResolution(problem) {
944
947
  if (isGameNotFoundProblem(problem)) {
945
948
  return [
946
- "Run `dreamboard sync --force` to recreate the remote game state from your current local files if this is a local workspace.",
947
- "If you meant to use an existing remote game, check that your selected `--env` points at the backend that has that game."
949
+ "Verify the project binding with `dreamboard project status --commit <rev>` after pushing the exact commit.",
950
+ "If you meant to use an existing remote project, check that your selected account and environment point at the backend that has that project."
948
951
  ].join(" ");
949
952
  }
950
953
  switch (problem.type) {
951
954
  case CLI_PROBLEM_TYPES.UNAUTHORIZED:
952
- return "Run `dreamboard login` to authenticate again.";
955
+ return "Run `dreamboard auth login` to authenticate again.";
953
956
  case CLI_PROBLEM_TYPES.FORBIDDEN:
954
- return "Check that the signed-in account has access to this game, or run `dreamboard login` with the correct account.";
957
+ return "Check that the signed-in account has access to this game, or run `dreamboard auth login` with the correct account.";
955
958
  case CLI_PROBLEM_TYPES.TOO_MANY_REQUESTS:
956
959
  return "Wait a moment, then retry the command.";
957
960
  case CLI_PROBLEM_TYPES.TRANSPORT_ERROR:
@@ -963,14 +966,14 @@ function getProblemResolution(problem) {
963
966
  case CLI_PROBLEM_TYPES.GAME_SLUG_CONFLICT:
964
967
  return "Choose a different game slug, or use the existing workspace for that slug.";
965
968
  case CLI_PROBLEM_TYPES.SOURCE_REVISION_NOT_FOUND:
966
- return "Run `dreamboard sync --force` to recreate the remote source revision from your current local files.";
969
+ return "Push the exact Git commit, then run `dreamboard project status --commit <rev> --wait` before retrying.";
967
970
  case CLI_PROBLEM_TYPES.SOURCE_REVISION_DRIFT:
968
971
  case CLI_PROBLEM_TYPES.AUTHORING_STATE_DRIFT:
969
972
  case CLI_PROBLEM_TYPES.STATE_CONFLICT:
970
- return "Run `dreamboard pull` to reconcile remote changes before retrying. If this local workspace is the source of truth, rerun the command with `--force` when supported.";
973
+ return "Resolve the Git/source conflict in your worktree, push the intended exact commit, and retry the command against that commit.";
971
974
  case CLI_PROBLEM_TYPES.SOURCE_REVISION_BASE_MISSING:
972
975
  case CLI_PROBLEM_TYPES.AUTHORING_STATE_BASE_MISSING:
973
- return "Run `dreamboard pull --force` in a clean workspace to recover the remote authored state. If the remote has no authored state, run `dreamboard sync --force` from the local source-of-truth workspace.";
976
+ return "Clone the project repository into a clean workspace or push the intended exact commit before retrying.";
974
977
  case CLI_PROBLEM_TYPES.INTERNAL_ERROR:
975
978
  return "Retry the command. If it still fails, include the request id when asking for help.";
976
979
  default:
@@ -1139,18 +1142,6 @@ async function getProjectCompiledResultSdk(projectId, compiledResultId) {
1139
1142
  }
1140
1143
  return data;
1141
1144
  }
1142
- async function queueProjectRevisionCompileSdk(options) {
1143
- const { data, error, response } = await queueProjectRevisionCompile({
1144
- path: {
1145
- projectId: options.projectId,
1146
- revisionDigest: options.revisionDigest
1147
- }
1148
- });
1149
- if (error || !data) {
1150
- throw toDreamboardApiError(error, response, "Failed to create compile job");
1151
- }
1152
- return data;
1153
- }
1154
1145
  async function waitForCompiledResultJobSdk(options) {
1155
1146
  const { gameId, projectId, jobId, onProgress } = options;
1156
1147
  let previousTransitionKey = null;
@@ -1234,75 +1225,9 @@ function isTransientJobPollMessage(message) {
1234
1225
  return normalized.includes("fetch failed") || normalized.includes("network") || normalized.includes("timeout") || normalized.includes("econnreset") || normalized.includes("econnrefused") || normalized.includes("socket");
1235
1226
  }
1236
1227
 
1237
- // src/services/project/local-maintainer-registry-shared.ts
1238
- import crypto2 from "crypto";
1239
- import path2 from "path";
1240
- var localRegistryAddress = readLocalRegistryAddress();
1241
- var LOCAL_REGISTRY_HOST = localRegistryAddress.host;
1242
- var LOCAL_REGISTRY_PORT = localRegistryAddress.port;
1243
- var LOCAL_REGISTRY_URL = `http://${LOCAL_REGISTRY_HOST}:${LOCAL_REGISTRY_PORT}`;
1244
- var LOCAL_SCOPE_NPMRC_CONTENT = `@dreamboard-games:registry=${LOCAL_REGISTRY_URL}
1245
- `;
1246
- function readLocalRegistryAddress() {
1247
- const urlOverride = process.env.DREAMBOARD_LOCAL_REGISTRY_URL?.trim();
1248
- const hostOverride = process.env.DREAMBOARD_LOCAL_REGISTRY_HOST?.trim();
1249
- const portOverride = process.env.DREAMBOARD_LOCAL_REGISTRY_PORT?.trim();
1250
- if (urlOverride) {
1251
- let parsed;
1252
- try {
1253
- parsed = new URL(urlOverride);
1254
- } catch {
1255
- throw new Error(
1256
- `Invalid DREAMBOARD_LOCAL_REGISTRY_URL '${urlOverride}'. Expected an http://host:port URL.`
1257
- );
1258
- }
1259
- if (parsed.protocol !== "http:" || !parsed.hostname || !parsed.port) {
1260
- throw new Error(
1261
- `Invalid DREAMBOARD_LOCAL_REGISTRY_URL '${urlOverride}'. Expected an http://host:port URL.`
1262
- );
1263
- }
1264
- return {
1265
- host: hostOverride || parsed.hostname,
1266
- port: parseLocalRegistryPort(portOverride || parsed.port)
1267
- };
1268
- }
1269
- return {
1270
- host: hostOverride || "127.0.0.1",
1271
- port: portOverride ? parseLocalRegistryPort(portOverride) : 4873
1272
- };
1273
- }
1274
- function parseLocalRegistryPort(raw) {
1275
- const port = Number.parseInt(raw, 10);
1276
- if (!Number.isInteger(port) || port < 1 || port > 65535) {
1277
- throw new Error(
1278
- `Invalid DREAMBOARD_LOCAL_REGISTRY_PORT '${raw}'. Expected a TCP port from 1 to 65535.`
1279
- );
1280
- }
1281
- return port;
1282
- }
1283
- function shortHash(value) {
1284
- return crypto2.createHash("sha256").update(value).digest("hex").slice(0, 12);
1285
- }
1286
- function isLocalMaintainerRegistryEnabled(apiBaseUrl) {
1287
- let isLocalLoopbackUrl = false;
1288
- try {
1289
- const parsed = new URL(apiBaseUrl);
1290
- isLocalLoopbackUrl = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
1291
- } catch {
1292
- isLocalLoopbackUrl = false;
1293
- }
1294
- return !IS_PUBLISHED_BUILD && (apiBaseUrl === ENVIRONMENT_CONFIGS.local?.apiBaseUrl || isLocalLoopbackUrl) && BUILD_CHANNEL === "development";
1295
- }
1296
- function didLocalMaintainerSnapshotChange(previous, next) {
1297
- if (!next) {
1298
- return false;
1299
- }
1300
- return previous?.snapshotId !== next.snapshotId;
1301
- }
1302
-
1303
1228
  // src/ui/playwright-runner.ts
1304
1229
  import os from "os";
1305
- import path3 from "path";
1230
+ import path2 from "path";
1306
1231
  function configurePlaywrightBrowsersPath() {
1307
1232
  if (process.env.PLAYWRIGHT_BROWSERS_PATH) {
1308
1233
  return;
@@ -1314,10 +1239,10 @@ function configurePlaywrightBrowsersPath() {
1314
1239
  } catch {
1315
1240
  return;
1316
1241
  }
1317
- if (!runtimeHome || path3.resolve(runtimeHome) === path3.resolve(realHome)) {
1242
+ if (!runtimeHome || path2.resolve(runtimeHome) === path2.resolve(realHome)) {
1318
1243
  return;
1319
1244
  }
1320
- const browserCachePath = process.platform === "darwin" ? path3.join(realHome, "Library", "Caches", "ms-playwright") : process.platform === "win32" ? path3.join(realHome, "AppData", "Local", "ms-playwright") : path3.join(realHome, ".cache", "ms-playwright");
1245
+ const browserCachePath = process.platform === "darwin" ? path2.join(realHome, "Library", "Caches", "ms-playwright") : process.platform === "win32" ? path2.join(realHome, "AppData", "Local", "ms-playwright") : path2.join(realHome, ".cache", "ms-playwright");
1321
1246
  process.env.PLAYWRIGHT_BROWSERS_PATH = browserCachePath;
1322
1247
  }
1323
1248
  async function buildBrowserAuthInitScript(config) {
@@ -1332,7 +1257,7 @@ async function waitForGameReady(page, timeoutMs = 6e4) {
1332
1257
  }
1333
1258
 
1334
1259
  // src/services/testing/reducer-native-test-harness.ts
1335
- import path6 from "path";
1260
+ import path5 from "path";
1336
1261
  import { randomUUID as randomUUID3 } from "crypto";
1337
1262
  import { createRequire as createRequire2 } from "module";
1338
1263
  import { pathToFileURL as pathToFileURL3 } from "url";
@@ -1358,18 +1283,6 @@ function createPersistedDevSession(input) {
1358
1283
  sessionId: input.sessionId
1359
1284
  };
1360
1285
  }
1361
- async function loadPersistedDevSession(sessionFilePath) {
1362
- if (!await exists(sessionFilePath)) {
1363
- return null;
1364
- }
1365
- const value = await readJsonFile(sessionFilePath);
1366
- if (!value.sessionId) {
1367
- return null;
1368
- }
1369
- return {
1370
- sessionId: value.sessionId
1371
- };
1372
- }
1373
1286
  function parseDevSeed(rawSeed) {
1374
1287
  return parseOptionalDevSeed(rawSeed) ?? DEFAULT_DEV_SEED;
1375
1288
  }
@@ -1415,7 +1328,7 @@ function extractUserIdFromJwt(token) {
1415
1328
  // src/utils/ts-module-loader.ts
1416
1329
  import { mkdtemp, rm, writeFile } from "fs/promises";
1417
1330
  import { tmpdir } from "os";
1418
- import path4 from "path";
1331
+ import path3 from "path";
1419
1332
  import { pathToFileURL } from "url";
1420
1333
  import { build } from "esbuild";
1421
1334
  var ESBUILD_EXTERNALS = [
@@ -1429,14 +1342,14 @@ function resolveSourceCheckoutBuildContext() {
1429
1342
  const repoRoot = resolveCliRepoRoot(import.meta.url);
1430
1343
  return {
1431
1344
  nodePaths: [
1432
- path4.join(repoRoot, "apps", "dreamboard-cli", "node_modules"),
1433
- path4.join(repoRoot, "node_modules")
1345
+ path3.join(repoRoot, "apps", "dreamboard-cli", "node_modules"),
1346
+ path3.join(repoRoot, "node_modules")
1434
1347
  ],
1435
1348
  plugins: [createRepoLocalPackageResolutionPlugin({ repoRoot })]
1436
1349
  };
1437
1350
  } catch {
1438
1351
  return {
1439
- nodePaths: [path4.join(process.cwd(), "node_modules")],
1352
+ nodePaths: [path3.join(process.cwd(), "node_modules")],
1440
1353
  plugins: []
1441
1354
  };
1442
1355
  }
@@ -1462,10 +1375,10 @@ async function bundleTypeScriptModuleText(entryPath, options = {}) {
1462
1375
  return output.text;
1463
1376
  }
1464
1377
  async function importTypeScriptModule(entryPath) {
1465
- const tempDir = await mkdtemp(path4.join(tmpdir(), "dreamboard-ts-module-"));
1466
- const outfile = path4.join(
1378
+ const tempDir = await mkdtemp(path3.join(tmpdir(), "dreamboard-ts-module-"));
1379
+ const outfile = path3.join(
1467
1380
  tempDir,
1468
- `${path4.basename(entryPath).replace(/\.[^.]+$/u, "")}.mjs`
1381
+ `${path3.basename(entryPath).replace(/\.[^.]+$/u, "")}.mjs`
1469
1382
  );
1470
1383
  try {
1471
1384
  const bundledText = await bundleTypeScriptModuleText(entryPath);
@@ -2055,11 +1968,11 @@ async function submitGameplayAuthorityAction(options) {
2055
1968
  }
2056
1969
 
2057
1970
  // src/services/dev-host/loader.ts
2058
- import path5 from "path";
1971
+ import path4 from "path";
2059
1972
  import { createRequire } from "module";
2060
1973
  import { pathToFileURL as pathToFileURL2 } from "url";
2061
1974
  async function loadProjectDevHost(projectRoot) {
2062
- const requireFromProject = createRequire(path5.join(projectRoot, "package.json"));
1975
+ const requireFromProject = createRequire(path4.join(projectRoot, "package.json"));
2063
1976
  let packageJsonPath;
2064
1977
  let entryPath;
2065
1978
  try {
@@ -2073,7 +1986,7 @@ async function loadProjectDevHost(projectRoot) {
2073
1986
  { cause: error }
2074
1987
  );
2075
1988
  }
2076
- const packageRoot = path5.dirname(packageJsonPath);
1989
+ const packageRoot = path4.dirname(packageJsonPath);
2077
1990
  if (!isPathInside(packageRoot, entryPath)) {
2078
1991
  throw new Error(
2079
1992
  "@dreamboard-games/dev-host resolved outside its installed package."
@@ -2099,8 +2012,8 @@ async function loadProjectDevHost(projectRoot) {
2099
2012
  };
2100
2013
  }
2101
2014
  function isPathInside(parent, candidate) {
2102
- const relativePath = path5.relative(parent, candidate);
2103
- return relativePath === "" || !relativePath.startsWith("..") && !path5.isAbsolute(relativePath);
2015
+ const relativePath = path4.relative(parent, candidate);
2016
+ return relativePath === "" || !relativePath.startsWith("..") && !path4.isAbsolute(relativePath);
2104
2017
  }
2105
2018
 
2106
2019
  // src/services/dev-host/platform.ts
@@ -2120,7 +2033,7 @@ async function resolveDevHostBearer(config) {
2120
2033
  if (!config.refreshToken) {
2121
2034
  return {
2122
2035
  kind: "permanent_invalid",
2123
- message: "Stored Dreamboard session is expired or invalid. Run `dreamboard login` to authenticate again."
2036
+ message: "Stored Dreamboard session is expired or invalid. Run `dreamboard auth login` to authenticate again."
2124
2037
  };
2125
2038
  }
2126
2039
  const resolved = await createUserTokenManager(config).resolveApiToken();
@@ -2219,15 +2132,15 @@ function findScenarioStackFrame(options) {
2219
2132
  if (!options.stack) {
2220
2133
  return null;
2221
2134
  }
2222
- const absolutePath = path6.resolve(options.scenarioFilePath);
2223
- const relativePath = path6.relative(options.projectRoot, absolutePath);
2224
- const normalizedRelativePath = relativePath.split(path6.sep).join("/");
2135
+ const absolutePath = path5.resolve(options.scenarioFilePath);
2136
+ const relativePath = path5.relative(options.projectRoot, absolutePath);
2137
+ const normalizedRelativePath = relativePath.split(path5.sep).join("/");
2225
2138
  const escapedAbsolutePath = escapeRegExp(absolutePath);
2226
2139
  const escapedRelativePath = escapeRegExp(normalizedRelativePath);
2227
2140
  const absoluteFrame = new RegExp(`${escapedAbsolutePath}:(\\d+):(\\d+)`);
2228
2141
  const relativeFrame = new RegExp(`${escapedRelativePath}:(\\d+):(\\d+)`);
2229
2142
  for (const line of options.stack.split("\n")) {
2230
- const normalizedLine = line.split(path6.sep).join("/");
2143
+ const normalizedLine = line.split(path5.sep).join("/");
2231
2144
  const match = normalizedLine.match(absoluteFrame) ?? normalizedLine.match(relativeFrame);
2232
2145
  if (match?.[1] && match?.[2]) {
2233
2146
  return `at ${normalizedRelativePath}:${match[1]}:${match[2]}`;
@@ -2241,7 +2154,7 @@ function escapeRegExp(value) {
2241
2154
  var projectReducerNativeModules = /* @__PURE__ */ new Map();
2242
2155
  function resolveProjectSdkModule(projectRoot, specifier) {
2243
2156
  const requireFromProject = createRequire2(
2244
- path6.join(projectRoot, "package.json")
2157
+ path5.join(projectRoot, "package.json")
2245
2158
  );
2246
2159
  return requireFromProject.resolve(specifier);
2247
2160
  }
@@ -2250,7 +2163,7 @@ async function importProjectSdkModule(projectRoot, specifier) {
2250
2163
  return await import(pathToFileURL3(modulePath).href);
2251
2164
  }
2252
2165
  async function loadProjectReducerNativeModules(projectRoot) {
2253
- const cacheKey = path6.resolve(projectRoot);
2166
+ const cacheKey = path5.resolve(projectRoot);
2254
2167
  const cached = projectReducerNativeModules.get(cacheKey);
2255
2168
  if (cached) {
2256
2169
  return cached;
@@ -2313,7 +2226,7 @@ async function discoverFiles(root, suffix) {
2313
2226
  const entries = await readdir(root, { withFileTypes: true });
2314
2227
  const files = [];
2315
2228
  for (const entry of entries) {
2316
- const entryPath = path6.join(root, entry.name);
2229
+ const entryPath = path5.join(root, entry.name);
2317
2230
  if (entry.isDirectory()) {
2318
2231
  files.push(...await discoverFiles(entryPath, suffix));
2319
2232
  continue;
@@ -2362,8 +2275,8 @@ function parseTypedScenarioDefinition(value) {
2362
2275
  };
2363
2276
  }
2364
2277
  async function isReducerNativeTestingWorkspace(projectRoot) {
2365
- return await exists(path6.join(projectRoot, "app", "game.ts")) && await exists(
2366
- path6.join(projectRoot, "shared", "generated", "ui-contract.ts")
2278
+ return await exists(path5.join(projectRoot, "app", "game.ts")) && await exists(
2279
+ path5.join(projectRoot, "shared", "generated", "ui-contract.ts")
2367
2280
  );
2368
2281
  }
2369
2282
  async function ensureReducerNativeTestingFiles(projectRoot) {
@@ -2391,7 +2304,7 @@ async function ensureReducerNativeTestingFiles(projectRoot) {
2391
2304
  testingContractPath,
2392
2305
  buildReducerTestingContractContent({ rejectionCodes })
2393
2306
  );
2394
- const header = "// Generated by dreamboard test generate. Do not edit by hand.\n";
2307
+ const header = "// Generated by dreamboard test. Do not edit by hand.\n";
2395
2308
  if (!await workspacePathExists(projectRoot, baseStatesPath)) {
2396
2309
  await writeWorkspaceTextFile(
2397
2310
  projectRoot,
@@ -2455,7 +2368,7 @@ var DEFAULT_REJECTION_CODES = [
2455
2368
  ];
2456
2369
  async function collectKnownRejectionCodes(projectRoot) {
2457
2370
  const knownCodes = new Set(DEFAULT_REJECTION_CODES);
2458
- const gamePath = path6.join(projectRoot, "app", "game.ts");
2371
+ const gamePath = path5.join(projectRoot, "app", "game.ts");
2459
2372
  if (!await exists(gamePath)) {
2460
2373
  return Array.from(knownCodes).sort(
2461
2374
  (left, right) => left.localeCompare(right)
@@ -2521,8 +2434,8 @@ async function loadTypedScenarios(projectRoot, options) {
2521
2434
  return loaded;
2522
2435
  }
2523
2436
  function reducerNativeTestHelperExternals(projectRoot, filePath) {
2524
- const testingTypesPath = path6.join(projectRoot, "test", "testing-types");
2525
- const relative = path6.relative(path6.dirname(filePath), testingTypesPath).replaceAll("\\", "/");
2437
+ const testingTypesPath = path5.join(projectRoot, "test", "testing-types");
2438
+ const relative = path5.relative(path5.dirname(filePath), testingTypesPath).replaceAll("\\", "/");
2526
2439
  const specifier = relative.startsWith(".") ? relative : `./${relative}`;
2527
2440
  return [specifier, `${specifier}.ts`, ...SDK_UI_RUNTIME_EXTERNALS];
2528
2441
  }
@@ -3038,7 +2951,7 @@ async function assertLiveMatchesShadow(runner, shadow, live) {
3038
2951
  }
3039
2952
  }
3040
2953
  async function loadBrowserDriver(projectRoot) {
3041
- const filePath = path6.join(projectRoot, "test", "browser-driver.ts");
2954
+ const filePath = path5.join(projectRoot, "test", "browser-driver.ts");
3042
2955
  if (!await exists(filePath)) {
3043
2956
  return null;
3044
2957
  }
@@ -3075,7 +2988,7 @@ function createScenarioSnapshotMatcher(options) {
3075
2988
  };
3076
2989
  const serialized = `${JSON.stringify(wrappedValue, null, 2)}
3077
2990
  `;
3078
- mkdirSync(path6.dirname(snapshotPath), { recursive: true });
2991
+ mkdirSync(path5.dirname(snapshotPath), { recursive: true });
3079
2992
  if (!existsSync(snapshotPath) || options.updateSnapshots) {
3080
2993
  writeFileSync(snapshotPath, serialized, "utf8");
3081
2994
  return;
@@ -3083,7 +2996,7 @@ function createScenarioSnapshotMatcher(options) {
3083
2996
  const previous = JSON.parse(readFileSync(snapshotPath, "utf8"));
3084
2997
  if (!deepEqual(previous.value, actual)) {
3085
2998
  throw new Error(
3086
- `Snapshot mismatch for scenario '${options.scenarioId}'. Re-run with --update-snapshots to refresh ${path6.relative(options.projectRoot, snapshotPath)}.`
2999
+ `Snapshot mismatch for scenario '${options.scenarioId}'. Re-run with --update-snapshots to refresh ${path5.relative(options.projectRoot, snapshotPath)}.`
3087
3000
  );
3088
3001
  }
3089
3002
  };
@@ -3348,7 +3261,7 @@ async function readMaterializedScenarioCache(options) {
3348
3261
  }
3349
3262
  async function writeMaterializedScenarioCache(options) {
3350
3263
  const cachePath = materializedScenarioCacheFilePath(options);
3351
- await ensureDir(path6.dirname(cachePath));
3264
+ await ensureDir(path5.dirname(cachePath));
3352
3265
  await writeWorkspaceJsonFile(
3353
3266
  options.projectRoot,
3354
3267
  materializedScenarioCachePath(options),
@@ -3415,12 +3328,12 @@ async function materializeScenarioReducerState(options) {
3415
3328
  const generatedBase = generatedBaseStates?.[baseStateKey(base.definition.id)];
3416
3329
  if (!generatedBase) {
3417
3330
  throw new Error(
3418
- `Missing generated base artifact for '${base.definition.id}'. Run 'dreamboard test generate' before using --from-scenario.`
3331
+ `Missing generated base artifact for '${base.definition.id}'. Run 'dreamboard test' before using --from-scenario.`
3419
3332
  );
3420
3333
  }
3421
3334
  if (typeof generatedBase.version !== "number") {
3422
3335
  throw new Error(
3423
- `Generated base artifact for '${base.definition.id}' is stale. Run 'dreamboard test generate' before using --from-scenario.`
3336
+ `Generated base artifact for '${base.definition.id}' is stale. Run 'dreamboard test' before using --from-scenario.`
3424
3337
  );
3425
3338
  }
3426
3339
  const canTrustGeneratedFingerprint = options.trustGeneratedFingerprint === true && generatedBase.fingerprint.compiledResultId === options.compiledResultId && generatedBase.fingerprint.gameId === options.gameId;
@@ -3449,10 +3362,10 @@ async function materializeScenarioReducerState(options) {
3449
3362
  }
3450
3363
  const [gameModule, manifestContractModule, modules] = await Promise.all([
3451
3364
  importTypeScriptModule(
3452
- path6.join(options.projectRoot, "app", "game.ts")
3365
+ path5.join(options.projectRoot, "app", "game.ts")
3453
3366
  ),
3454
3367
  importTypeScriptModule(
3455
- path6.join(options.projectRoot, "shared", "manifest-contract.ts")
3368
+ path5.join(options.projectRoot, "shared", "manifest-contract.ts")
3456
3369
  ),
3457
3370
  loadProjectReducerNativeModules(options.projectRoot)
3458
3371
  ]);
@@ -3605,7 +3518,7 @@ function writeProjectionSnapshots(options) {
3605
3518
  function validateTypedScenarioBases(scenarios, basesById) {
3606
3519
  const available = new Set(basesById.keys());
3607
3520
  const invalid = scenarios.filter((scenario) => !available.has(scenario.definition.from)).map(
3608
- (scenario) => path6.relative(process.cwd(), scenario.filePath) + ` -> '${scenario.definition.from}'`
3521
+ (scenario) => path5.relative(process.cwd(), scenario.filePath) + ` -> '${scenario.definition.from}'`
3609
3522
  );
3610
3523
  if (invalid.length > 0) {
3611
3524
  throw new Error(
@@ -3619,12 +3532,12 @@ async function writeReducerNativeGeneratedFiles(options) {
3619
3532
  const manifestHash = hashContent(JSON.stringify(manifest));
3620
3533
  const appBundleHash = hashContent(
3621
3534
  await bundleTypeScriptModuleText(
3622
- path6.join(options.projectRoot, "app", "game.ts")
3535
+ path5.join(options.projectRoot, "app", "game.ts")
3623
3536
  )
3624
3537
  );
3625
3538
  const uiContractHash = hashContent(
3626
3539
  await bundleTypeScriptModuleText(
3627
- path6.join(options.projectRoot, "shared", "generated", "ui-contract.ts"),
3540
+ path5.join(options.projectRoot, "shared", "generated", "ui-contract.ts"),
3628
3541
  { external: SDK_UI_RUNTIME_EXTERNALS }
3629
3542
  )
3630
3543
  );
@@ -3636,10 +3549,10 @@ async function writeReducerNativeGeneratedFiles(options) {
3636
3549
  const baseStates = {};
3637
3550
  const [gameModule, manifestContractModule, modules] = await Promise.all([
3638
3551
  importTypeScriptModule(
3639
- path6.join(options.projectRoot, "app", "game.ts")
3552
+ path5.join(options.projectRoot, "app", "game.ts")
3640
3553
  ),
3641
3554
  importTypeScriptModule(
3642
- path6.join(options.projectRoot, "shared", "manifest-contract.ts")
3555
+ path5.join(options.projectRoot, "shared", "manifest-contract.ts")
3643
3556
  ),
3644
3557
  loadProjectReducerNativeModules(options.projectRoot)
3645
3558
  ]);
@@ -3739,7 +3652,7 @@ async function writeReducerNativeGeneratedFiles(options) {
3739
3652
  shadow
3740
3653
  });
3741
3654
  }
3742
- const header = "// Generated by dreamboard test generate. Do not edit by hand.\n";
3655
+ const header = "// Generated by dreamboard test. Do not edit by hand.\n";
3743
3656
  await writeWorkspaceTextFile(
3744
3657
  options.projectRoot,
3745
3658
  "test/generated/base-states.generated.ts",
@@ -3760,7 +3673,7 @@ export declare const BASE_STATES_CONTRACT_FINGERPRINT: string | undefined;
3760
3673
  `${header}export const SCENARIO_MANIFEST = ${JSON.stringify(
3761
3674
  options.scenarios.map((scenario) => ({
3762
3675
  id: scenario.definition.id,
3763
- filePath: path6.relative(generatedDir, scenario.filePath),
3676
+ filePath: path5.relative(generatedDir, scenario.filePath),
3764
3677
  base: scenario.definition.from,
3765
3678
  runners: normalizeScenarioRunners(scenario.definition.runners)
3766
3679
  })),
@@ -3781,7 +3694,7 @@ export declare const BASE_STATES_CONTRACT_FINGERPRINT: string | undefined;
3781
3694
  );
3782
3695
  }
3783
3696
  async function loadGeneratedBaseStates(projectRoot) {
3784
- const filePath = path6.join(
3697
+ const filePath = path5.join(
3785
3698
  projectRoot,
3786
3699
  "test",
3787
3700
  "generated",
@@ -3794,7 +3707,7 @@ async function loadGeneratedBaseStates(projectRoot) {
3794
3707
  return module.BASE_STATES ?? null;
3795
3708
  }
3796
3709
  async function loadGeneratedScenarioManifest(projectRoot) {
3797
- const filePath = path6.join(
3710
+ const filePath = path5.join(
3798
3711
  projectRoot,
3799
3712
  "test",
3800
3713
  "generated",
@@ -3819,7 +3732,7 @@ function validateGeneratedFingerprint(options) {
3819
3732
  const mismatches = [];
3820
3733
  if (options.generated.contractFingerprint && options.current.contractFingerprint && options.generated.contractFingerprint !== options.current.contractFingerprint) {
3821
3734
  const error = new Error(
3822
- `Base states were generated for contract ${options.generated.contractFingerprint} but the current contract is ${options.current.contractFingerprint}. Remedy: run \`dreamboard test generate\`, then re-run the tests.`
3735
+ `Base states were generated for contract ${options.generated.contractFingerprint} but the current contract is ${options.current.contractFingerprint}. Remedy: run \`dreamboard test\`, then re-run the tests.`
3823
3736
  );
3824
3737
  error.code = STALE_CONTRACT_ARTIFACT_CODE;
3825
3738
  throw error;
@@ -3850,7 +3763,7 @@ function validateGeneratedFingerprint(options) {
3850
3763
  }
3851
3764
  if (mismatches.length > 0) {
3852
3765
  throw new Error(
3853
- `${mismatches.join("; ")}. Run 'dreamboard test generate' to refresh reducer-native base artifacts.`
3766
+ `${mismatches.join("; ")}. Run 'dreamboard test' to refresh reducer-native base artifacts.`
3854
3767
  );
3855
3768
  }
3856
3769
  }
@@ -3858,7 +3771,7 @@ async function currentFingerprint(options) {
3858
3771
  const manifest = await loadManifest(options.projectRoot);
3859
3772
  const [gameModule, modules] = await Promise.all([
3860
3773
  importTypeScriptModule(
3861
- path6.join(options.projectRoot, "app", "game.ts")
3774
+ path5.join(options.projectRoot, "app", "game.ts")
3862
3775
  ),
3863
3776
  loadProjectReducerNativeModules(options.projectRoot)
3864
3777
  ]);
@@ -3900,12 +3813,12 @@ async function currentFingerprint(options) {
3900
3813
  manifestHash: hashContent(JSON.stringify(manifest)),
3901
3814
  appBundleHash: hashContent(
3902
3815
  await bundleTypeScriptModuleText(
3903
- path6.join(options.projectRoot, "app", "game.ts")
3816
+ path5.join(options.projectRoot, "app", "game.ts")
3904
3817
  )
3905
3818
  ),
3906
3819
  uiContractHash: hashContent(
3907
3820
  await bundleTypeScriptModuleText(
3908
- path6.join(options.projectRoot, "shared", "generated", "ui-contract.ts"),
3821
+ path5.join(options.projectRoot, "shared", "generated", "ui-contract.ts"),
3909
3822
  { external: SDK_UI_RUNTIME_EXTERNALS }
3910
3823
  )
3911
3824
  ),
@@ -3955,10 +3868,10 @@ async function runReducerNativeScenarios(options) {
3955
3868
  loadGeneratedBaseStates(options.projectRoot),
3956
3869
  loadManifest(options.projectRoot),
3957
3870
  importTypeScriptModule(
3958
- path6.join(options.projectRoot, "app", "game.ts")
3871
+ path5.join(options.projectRoot, "app", "game.ts")
3959
3872
  ),
3960
3873
  importTypeScriptModule(
3961
- path6.join(options.projectRoot, "shared", "manifest-contract.ts")
3874
+ path5.join(options.projectRoot, "shared", "manifest-contract.ts")
3962
3875
  ),
3963
3876
  loadProjectReducerNativeModules(options.projectRoot)
3964
3877
  ]);
@@ -4010,7 +3923,7 @@ async function runReducerNativeScenarios(options) {
4010
3923
  });
4011
3924
  } else if (options.runner !== "reducer") {
4012
3925
  throw new Error(
4013
- "Missing reducer-native generated base artifacts. Run 'dreamboard test generate' first."
3926
+ "Missing reducer-native generated base artifacts. Run 'dreamboard test' first."
4014
3927
  );
4015
3928
  }
4016
3929
  let scenarioBrowser = null;
@@ -4036,7 +3949,7 @@ async function runReducerNativeScenarios(options) {
4036
3949
  const parentArtifact = generatedBaseStates?.[baseStateKey(base.definition.extends)];
4037
3950
  if (!parentArtifact) {
4038
3951
  throw new Error(
4039
- `Base '${base.definition.id}' extends '${base.definition.extends}', but the parent artifact is missing. Run 'dreamboard test generate' first.`
3952
+ `Base '${base.definition.id}' extends '${base.definition.extends}', but the parent artifact is missing. Run 'dreamboard test' first.`
4040
3953
  );
4041
3954
  }
4042
3955
  shadow.hydrate(parentArtifact.snapshot, parentArtifact.version);
@@ -4124,9 +4037,9 @@ async function runReducerNativeScenarios(options) {
4124
4037
  if (startError || !started) {
4125
4038
  throw new Error("Failed to start browser-runner session.");
4126
4039
  }
4127
- const devDir = path6.join(options.projectRoot, PROJECT_DIR_NAME, "dev");
4040
+ const devDir = path5.join(options.projectRoot, PROJECT_DIR_NAME, "dev");
4128
4041
  await ensureDir(devDir);
4129
- const sessionFilePath = path6.join(devDir, "session.json");
4042
+ const sessionFilePath = path5.join(devDir, "session.json");
4130
4043
  await writeJsonFile(
4131
4044
  sessionFilePath,
4132
4045
  createPersistedDevSession({ sessionId: session.sessionId })
@@ -4239,6 +4152,72 @@ async function runReducerNativeScenarios(options) {
4239
4152
  return { passed, failed, results };
4240
4153
  }
4241
4154
 
4155
+ // src/services/project/local-maintainer-registry-shared.ts
4156
+ import crypto2 from "crypto";
4157
+ import path6 from "path";
4158
+ var localRegistryAddress = readLocalRegistryAddress();
4159
+ var LOCAL_REGISTRY_HOST = localRegistryAddress.host;
4160
+ var LOCAL_REGISTRY_PORT = localRegistryAddress.port;
4161
+ var LOCAL_REGISTRY_URL = `http://${LOCAL_REGISTRY_HOST}:${LOCAL_REGISTRY_PORT}`;
4162
+ var LOCAL_SCOPE_NPMRC_CONTENT = `@dreamboard-games:registry=${LOCAL_REGISTRY_URL}
4163
+ `;
4164
+ function readLocalRegistryAddress() {
4165
+ const urlOverride = process.env.DREAMBOARD_LOCAL_REGISTRY_URL?.trim();
4166
+ const hostOverride = process.env.DREAMBOARD_LOCAL_REGISTRY_HOST?.trim();
4167
+ const portOverride = process.env.DREAMBOARD_LOCAL_REGISTRY_PORT?.trim();
4168
+ if (urlOverride) {
4169
+ let parsed;
4170
+ try {
4171
+ parsed = new URL(urlOverride);
4172
+ } catch {
4173
+ throw new Error(
4174
+ `Invalid DREAMBOARD_LOCAL_REGISTRY_URL '${urlOverride}'. Expected an http://host:port URL.`
4175
+ );
4176
+ }
4177
+ if (parsed.protocol !== "http:" || !parsed.hostname || !parsed.port) {
4178
+ throw new Error(
4179
+ `Invalid DREAMBOARD_LOCAL_REGISTRY_URL '${urlOverride}'. Expected an http://host:port URL.`
4180
+ );
4181
+ }
4182
+ return {
4183
+ host: hostOverride || parsed.hostname,
4184
+ port: parseLocalRegistryPort(portOverride || parsed.port)
4185
+ };
4186
+ }
4187
+ return {
4188
+ host: hostOverride || "127.0.0.1",
4189
+ port: portOverride ? parseLocalRegistryPort(portOverride) : 4873
4190
+ };
4191
+ }
4192
+ function parseLocalRegistryPort(raw) {
4193
+ const port = Number.parseInt(raw, 10);
4194
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
4195
+ throw new Error(
4196
+ `Invalid DREAMBOARD_LOCAL_REGISTRY_PORT '${raw}'. Expected a TCP port from 1 to 65535.`
4197
+ );
4198
+ }
4199
+ return port;
4200
+ }
4201
+ function shortHash(value) {
4202
+ return crypto2.createHash("sha256").update(value).digest("hex").slice(0, 12);
4203
+ }
4204
+ function isLocalMaintainerRegistryEnabled(apiBaseUrl) {
4205
+ let isLocalLoopbackUrl = false;
4206
+ try {
4207
+ const parsed = new URL(apiBaseUrl);
4208
+ isLocalLoopbackUrl = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
4209
+ } catch {
4210
+ isLocalLoopbackUrl = false;
4211
+ }
4212
+ return !IS_PUBLISHED_BUILD && (apiBaseUrl === ENVIRONMENT_CONFIGS.local?.apiBaseUrl || isLocalLoopbackUrl) && BUILD_CHANNEL === "development";
4213
+ }
4214
+ function didLocalMaintainerSnapshotChange(previous, next) {
4215
+ if (!next) {
4216
+ return false;
4217
+ }
4218
+ return previous?.snapshotId !== next.snapshotId;
4219
+ }
4220
+
4242
4221
  export {
4243
4222
  createPkcePair,
4244
4223
  buildClerkAuthorizationUrl,
@@ -4252,27 +4231,20 @@ export {
4252
4231
  configureClient,
4253
4232
  refreshResolvedAuthSession,
4254
4233
  requireAuth,
4255
- valueOrUndefined,
4256
4234
  getAuthTokenExpiry,
4257
4235
  resolveProjectContext,
4258
4236
  parseConfigFlags,
4259
4237
  parsePlayerCountFlags,
4260
4238
  parseNewCommandArgs,
4261
4239
  parseCloneCommandArgs,
4262
- parseQueryCommandArgs,
4263
- parsePullCommandArgs,
4264
- parseSyncCommandArgs,
4265
- parseCompileCommandArgs,
4266
- parseStatusCommandArgs,
4240
+ parseCommitScopedCommandArgs,
4241
+ parseBuildCommandArgs,
4242
+ parseReleasePublishCommandArgs,
4267
4243
  parseDevCommandArgs,
4268
- parseJoinCommandArgs,
4269
- parseLoginCommandArgs,
4270
- parseConfigCommandArgs,
4271
4244
  parseAuthCommandArgs,
4272
4245
  CONFIG_FLAG_ARGS,
4273
4246
  STALE_CONTRACT_ARTIFACT_CODE,
4274
4247
  STALE_CONTRACT_ARTIFACT_EXIT_CODE,
4275
- toApiProblem,
4276
4248
  toDreamboardApiError,
4277
4249
  isDreamboardApiError,
4278
4250
  isStaleContractArtifactMessage,
@@ -4286,20 +4258,13 @@ export {
4286
4258
  findCompiledResultsForAuthoringState,
4287
4259
  findProjectCompiledResultsForRevision,
4288
4260
  getProjectCompiledResultSdk,
4289
- queueProjectRevisionCompileSdk,
4290
4261
  waitForCompiledResultJobSdk,
4291
- LOCAL_REGISTRY_URL,
4292
- shortHash,
4293
- isLocalMaintainerRegistryEnabled,
4294
- didLocalMaintainerSnapshotChange,
4295
4262
  createPersistedDevSession,
4296
- loadPersistedDevSession,
4297
4263
  parseDevSeed,
4298
4264
  extractUserIdFromJwt,
4299
4265
  loadProjectDevHost,
4300
4266
  createCliDevHostPlatform,
4301
4267
  importTypeScriptModule,
4302
- submitGameplayAuthorityAction,
4303
4268
  configurePlaywrightBrowsersPath,
4304
4269
  resolveSetupProfileSelectionForSession,
4305
4270
  projectIdFromSessionGameSource,
@@ -4307,6 +4272,10 @@ export {
4307
4272
  ensureReducerNativeTestingFiles,
4308
4273
  createSessionFromScenario,
4309
4274
  generateReducerNativeArtifacts,
4310
- runReducerNativeScenarios
4275
+ runReducerNativeScenarios,
4276
+ LOCAL_REGISTRY_URL,
4277
+ shortHash,
4278
+ isLocalMaintainerRegistryEnabled,
4279
+ didLocalMaintainerSnapshotChange
4311
4280
  };
4312
- //# sourceMappingURL=chunk-R6RB4EKH.js.map
4281
+ //# sourceMappingURL=chunk-5PJWUB6W.js.map