@dreamboard-games/cli 0.1.30-alpha.29 → 0.1.30-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/agent-verifier/agent-workspace-verifier.mjs +360 -17
- package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -1
- package/dist/agent-verifier/{chunk-IWB4L2HV.mjs → chunk-FNSHNMDY.mjs} +51 -5
- package/dist/agent-verifier/chunk-FNSHNMDY.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-RDYXWXXC.mjs → chunk-LMW66VBH.mjs} +2 -11
- package/dist/agent-verifier/{chunk-RDYXWXXC.mjs.map → chunk-LMW66VBH.mjs.map} +1 -1
- package/dist/agent-verifier/{chunk-TIDX3YLW.mjs → chunk-M6YNQZCC.mjs} +2 -2
- package/dist/agent-verifier/{chunk-Z7UBAREF.mjs → chunk-QMOBTQ5G.mjs} +7 -9
- package/dist/agent-verifier/chunk-QMOBTQ5G.mjs.map +1 -0
- package/dist/agent-verifier/{chunk-F2DIOJJZ.mjs → chunk-XCQQIPCO.mjs} +5 -46
- package/dist/agent-verifier/chunk-XCQQIPCO.mjs.map +1 -0
- package/dist/agent-verifier/{global-config-IXZLY4BS.mjs → global-config-SWWR2LP4.mjs} +3 -4
- package/dist/agent-verifier/{materialize-workspace-XYYCQQGB.mjs → materialize-workspace-K4WYFG5E.mjs} +5 -5
- package/dist/agent-verifier/{reducer-native-test-harness-BY5SZ7XE.mjs → reducer-native-test-harness-UFMSNNDY.mjs} +49 -576
- package/dist/agent-verifier/reducer-native-test-harness-UFMSNNDY.mjs.map +1 -0
- package/dist/agent-verifier/{static-scaffold-M7QPX76Z.mjs → static-scaffold-MHVM63HU.mjs} +4 -4
- package/dist/authoring-compatibility-internal.js +1 -1
- package/dist/{chunk-QIVDPQME.js → chunk-I4SZ7FA4.js} +9 -64
- package/dist/{chunk-QIVDPQME.js.map → chunk-I4SZ7FA4.js.map} +1 -1
- package/dist/{chunk-NFCRMXEV.js → chunk-RTNKVNQA.js} +52 -624
- package/dist/chunk-RTNKVNQA.js.map +1 -0
- package/dist/index.js +318 -369
- package/dist/index.js.map +1 -1
- package/dist/internal.js +23 -3
- package/dist/internal.js.map +1 -1
- package/package.json +1 -1
- package/release/authoring-release-set.json +2 -2
- package/skills/dreamboard/SKILL.md +1 -1
- package/skills/dreamboard/references/cli.md +2 -3
- package/skills/dreamboard/references/quickstart.md +1 -1
- package/skills/dreamboard/references/testing.md +0 -7
- package/dist/agent-verifier/chunk-B7M2TJSP.mjs +0 -363
- package/dist/agent-verifier/chunk-B7M2TJSP.mjs.map +0 -1
- package/dist/agent-verifier/chunk-F2DIOJJZ.mjs.map +0 -1
- package/dist/agent-verifier/chunk-IWB4L2HV.mjs.map +0 -1
- package/dist/agent-verifier/chunk-UXGTT25Q.mjs +0 -59
- package/dist/agent-verifier/chunk-UXGTT25Q.mjs.map +0 -1
- package/dist/agent-verifier/chunk-Z7UBAREF.mjs.map +0 -1
- package/dist/agent-verifier/reducer-native-test-harness-BY5SZ7XE.mjs.map +0 -1
- package/dist/chunk-NFCRMXEV.js.map +0 -1
- /package/dist/agent-verifier/{chunk-TIDX3YLW.mjs.map → chunk-M6YNQZCC.mjs.map} +0 -0
- /package/dist/agent-verifier/{global-config-IXZLY4BS.mjs.map → global-config-SWWR2LP4.mjs.map} +0 -0
- /package/dist/agent-verifier/{materialize-workspace-XYYCQQGB.mjs.map → materialize-workspace-K4WYFG5E.mjs.map} +0 -0
- /package/dist/agent-verifier/{static-scaffold-M7QPX76Z.mjs.map → static-scaffold-MHVM63HU.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -8,28 +8,22 @@ import {
|
|
|
8
8
|
STALE_CONTRACT_ARTIFACT_EXIT_CODE,
|
|
9
9
|
buildClerkAuthorizationUrl,
|
|
10
10
|
configureClient,
|
|
11
|
-
createCliDevHostPlatform,
|
|
12
|
-
createPersistedDevSession,
|
|
13
11
|
createPkcePair,
|
|
14
12
|
createSessionFromScenario,
|
|
15
13
|
createUserTokenManager,
|
|
16
14
|
didLocalMaintainerSnapshotChange,
|
|
17
15
|
exchangeClerkOAuthCode,
|
|
18
16
|
exchangeDreamboardUserToken,
|
|
19
|
-
extractUserIdFromJwt,
|
|
20
|
-
findProjectCompiledResultsForRevision,
|
|
21
17
|
formatCliError,
|
|
22
18
|
generateReducerNativeArtifacts,
|
|
23
19
|
getAuthTokenExpiry,
|
|
24
20
|
getCliErrorExitCode,
|
|
25
|
-
getProjectCompiledResultSdk,
|
|
26
21
|
importTypeScriptModule,
|
|
27
22
|
isDreamboardApiError,
|
|
28
23
|
isLocalMaintainerRegistryEnabled,
|
|
29
24
|
isReducerNativeTestingWorkspace,
|
|
30
25
|
isStaleContractArtifactError,
|
|
31
26
|
isStaleContractArtifactMessage,
|
|
32
|
-
loadProjectDevHost,
|
|
33
27
|
normalizeSlug,
|
|
34
28
|
parseAuthCommandArgs,
|
|
35
29
|
parseBuildCommandArgs,
|
|
@@ -37,7 +31,6 @@ import {
|
|
|
37
31
|
parseCommitScopedCommandArgs,
|
|
38
32
|
parseConfigFlags,
|
|
39
33
|
parseDevCommandArgs,
|
|
40
|
-
parseDevSeed,
|
|
41
34
|
parseNewCommandArgs,
|
|
42
35
|
parsePlayerCountFlags,
|
|
43
36
|
parsePositiveInt,
|
|
@@ -56,7 +49,7 @@ import {
|
|
|
56
49
|
titleFromSlug,
|
|
57
50
|
toDreamboardApiError,
|
|
58
51
|
waitForCompiledResultJobSdk
|
|
59
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-RTNKVNQA.js";
|
|
60
53
|
import {
|
|
61
54
|
applyWorkspaceCodegen,
|
|
62
55
|
collectLocalFiles,
|
|
@@ -71,12 +64,9 @@ import {
|
|
|
71
64
|
getApiVersion,
|
|
72
65
|
getCurrentAuthUser,
|
|
73
66
|
getCurrentProjectRelease,
|
|
74
|
-
getProjectAuthoringState,
|
|
75
67
|
getProjectBySlug,
|
|
76
68
|
getProjectCommitStatus,
|
|
77
|
-
getProjectCompileState,
|
|
78
69
|
getProjectLocalMaintainerRegistry,
|
|
79
|
-
getProjectPendingAuthoringSync,
|
|
80
70
|
getProjectRepository,
|
|
81
71
|
getSessionSnapshot,
|
|
82
72
|
installFrozenWorkspaceDependencies,
|
|
@@ -94,7 +84,7 @@ import {
|
|
|
94
84
|
updateProjectLocalMaintainerRegistry,
|
|
95
85
|
updateProjectState,
|
|
96
86
|
writeSnapshot
|
|
97
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-I4SZ7FA4.js";
|
|
98
88
|
import {
|
|
99
89
|
clearCredentials,
|
|
100
90
|
getActiveCredentialBackendName,
|
|
@@ -1940,7 +1930,7 @@ password=${response.password}
|
|
|
1940
1930
|
async function resolveGitCredential(input) {
|
|
1941
1931
|
const protocol = input.request.protocol?.toLowerCase();
|
|
1942
1932
|
const host = input.request.host?.toLowerCase();
|
|
1943
|
-
const
|
|
1933
|
+
const path11 = normalizeCredentialPath(input.request.path);
|
|
1944
1934
|
const allowedHosts = new Set(
|
|
1945
1935
|
input.policy.allowedHosts.map((value) => value.toLowerCase())
|
|
1946
1936
|
);
|
|
@@ -1952,7 +1942,7 @@ async function resolveGitCredential(input) {
|
|
|
1952
1942
|
if (!secureProtocol) {
|
|
1953
1943
|
return null;
|
|
1954
1944
|
}
|
|
1955
|
-
if (!
|
|
1945
|
+
if (!path11 || !pathPattern.test(path11)) {
|
|
1956
1946
|
return null;
|
|
1957
1947
|
}
|
|
1958
1948
|
const token = await input.tokenManager.resolveGitToken();
|
|
@@ -2957,9 +2947,63 @@ var build_default = defineCommand({
|
|
|
2957
2947
|
});
|
|
2958
2948
|
|
|
2959
2949
|
// src/commands/dev.ts
|
|
2960
|
-
import
|
|
2950
|
+
import path7 from "path";
|
|
2961
2951
|
import { createHash } from "crypto";
|
|
2962
2952
|
|
|
2953
|
+
// src/utils/dev-session.ts
|
|
2954
|
+
import { randomInt } from "crypto";
|
|
2955
|
+
var DEFAULT_DEV_SEED = 1337;
|
|
2956
|
+
var MIN_KOTLIN_LONG = -9223372036854775808n;
|
|
2957
|
+
var MAX_KOTLIN_LONG = 9223372036854775807n;
|
|
2958
|
+
var MIN_SAFE_SEED = BigInt(Number.MIN_SAFE_INTEGER);
|
|
2959
|
+
var MAX_SAFE_SEED = BigInt(Number.MAX_SAFE_INTEGER);
|
|
2960
|
+
function createPersistedDevSession(input) {
|
|
2961
|
+
return {
|
|
2962
|
+
sessionId: input.sessionId
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2965
|
+
function parseDevSeed(rawSeed) {
|
|
2966
|
+
return parseOptionalDevSeed(rawSeed) ?? DEFAULT_DEV_SEED;
|
|
2967
|
+
}
|
|
2968
|
+
function parseOptionalDevSeed(rawSeed) {
|
|
2969
|
+
const value = rawSeed?.trim();
|
|
2970
|
+
if (!value) {
|
|
2971
|
+
return void 0;
|
|
2972
|
+
}
|
|
2973
|
+
if (!/^-?\d+$/.test(value)) {
|
|
2974
|
+
throw new Error("seed must be an integer");
|
|
2975
|
+
}
|
|
2976
|
+
const parsed = BigInt(value);
|
|
2977
|
+
if (parsed < MIN_KOTLIN_LONG || parsed > MAX_KOTLIN_LONG) {
|
|
2978
|
+
throw new Error("seed must be within signed 64-bit integer range");
|
|
2979
|
+
}
|
|
2980
|
+
if (parsed < MIN_SAFE_SEED || parsed > MAX_SAFE_SEED) {
|
|
2981
|
+
throw new Error(
|
|
2982
|
+
`seed must be within JavaScript safe integer range (${Number.MIN_SAFE_INTEGER}..${Number.MAX_SAFE_INTEGER})`
|
|
2983
|
+
);
|
|
2984
|
+
}
|
|
2985
|
+
return Number(parsed);
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2988
|
+
// src/utils/jwt.ts
|
|
2989
|
+
function extractUserIdFromJwt(token) {
|
|
2990
|
+
if (!token) {
|
|
2991
|
+
return null;
|
|
2992
|
+
}
|
|
2993
|
+
const parts = token.split(".");
|
|
2994
|
+
if (parts.length < 2) {
|
|
2995
|
+
return null;
|
|
2996
|
+
}
|
|
2997
|
+
try {
|
|
2998
|
+
const payload = JSON.parse(
|
|
2999
|
+
Buffer.from(parts[1], "base64url").toString("utf8")
|
|
3000
|
+
);
|
|
3001
|
+
return typeof payload.sub === "string" ? payload.sub : null;
|
|
3002
|
+
} catch {
|
|
3003
|
+
return null;
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
|
|
2963
3007
|
// src/utils/player-count.ts
|
|
2964
3008
|
async function resolvePlayerCount(projectRoot, flags) {
|
|
2965
3009
|
const rawPlayers = flags.players ?? flags["player-count"];
|
|
@@ -2976,6 +3020,79 @@ async function resolvePlayerCount(projectRoot, flags) {
|
|
|
2976
3020
|
return Math.max(1, Math.floor(minPlayers));
|
|
2977
3021
|
}
|
|
2978
3022
|
|
|
3023
|
+
// src/services/dev-host/loader.ts
|
|
3024
|
+
import path from "path";
|
|
3025
|
+
import { createRequire } from "module";
|
|
3026
|
+
import { pathToFileURL } from "url";
|
|
3027
|
+
async function loadProjectDevHost(projectRoot) {
|
|
3028
|
+
const requireFromProject = createRequire(path.join(projectRoot, "package.json"));
|
|
3029
|
+
let packageJsonPath;
|
|
3030
|
+
let entryPath;
|
|
3031
|
+
try {
|
|
3032
|
+
packageJsonPath = requireFromProject.resolve(
|
|
3033
|
+
"@dreamboard-games/dev-host/package.json"
|
|
3034
|
+
);
|
|
3035
|
+
entryPath = requireFromProject.resolve("@dreamboard-games/dev-host");
|
|
3036
|
+
} catch (error) {
|
|
3037
|
+
throw new Error(
|
|
3038
|
+
"Install @dreamboard-games/dev-host in this workspace before running dreamboard dev or browser tests.",
|
|
3039
|
+
{ cause: error }
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
3042
|
+
const packageRoot = path.dirname(packageJsonPath);
|
|
3043
|
+
if (!isPathInside(packageRoot, entryPath)) {
|
|
3044
|
+
throw new Error(
|
|
3045
|
+
"@dreamboard-games/dev-host resolved outside its installed package."
|
|
3046
|
+
);
|
|
3047
|
+
}
|
|
3048
|
+
const packageJson = requireFromProject(packageJsonPath);
|
|
3049
|
+
if (packageJson.name !== "@dreamboard-games/dev-host" || typeof packageJson.version !== "string" || packageJson.version.length === 0) {
|
|
3050
|
+
throw new Error("Installed @dreamboard-games/dev-host metadata is invalid.");
|
|
3051
|
+
}
|
|
3052
|
+
const loaded = await import(pathToFileURL(entryPath).href);
|
|
3053
|
+
if (loaded.protocolVersion !== 1 || typeof loaded.start !== "function") {
|
|
3054
|
+
throw new Error(
|
|
3055
|
+
"Installed @dreamboard-games/dev-host does not expose DevHostModuleV1."
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
return {
|
|
3059
|
+
packageRoot,
|
|
3060
|
+
packageVersion: packageJson.version,
|
|
3061
|
+
module: {
|
|
3062
|
+
protocolVersion: loaded.protocolVersion,
|
|
3063
|
+
start: loaded.start
|
|
3064
|
+
}
|
|
3065
|
+
};
|
|
3066
|
+
}
|
|
3067
|
+
function isPathInside(parent, candidate) {
|
|
3068
|
+
const relativePath = path.relative(parent, candidate);
|
|
3069
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
// src/services/dev-host/platform.ts
|
|
3073
|
+
function createCliDevHostPlatform(config) {
|
|
3074
|
+
return {
|
|
3075
|
+
resolveBearer: () => resolveDevHostBearer(config)
|
|
3076
|
+
};
|
|
3077
|
+
}
|
|
3078
|
+
async function resolveDevHostBearer(config) {
|
|
3079
|
+
const localHarnessToken = resolveLocalHarnessAccessToken(config);
|
|
3080
|
+
if (localHarnessToken) {
|
|
3081
|
+
return { kind: "ok", token: localHarnessToken };
|
|
3082
|
+
}
|
|
3083
|
+
if (config.refreshTokenSource !== "global") {
|
|
3084
|
+
return { kind: "ok", token: config.authToken ?? null };
|
|
3085
|
+
}
|
|
3086
|
+
if (!config.refreshToken) {
|
|
3087
|
+
return {
|
|
3088
|
+
kind: "permanent_invalid",
|
|
3089
|
+
message: "Stored Dreamboard session is expired or invalid. Run `dreamboard auth login` to authenticate again."
|
|
3090
|
+
};
|
|
3091
|
+
}
|
|
3092
|
+
const resolved = await createUserTokenManager(config).resolveApiToken();
|
|
3093
|
+
return { kind: "ok", token: resolved?.token ?? null };
|
|
3094
|
+
}
|
|
3095
|
+
|
|
2979
3096
|
// src/services/project/remote-project.ts
|
|
2980
3097
|
async function resolveRemoteProject(options) {
|
|
2981
3098
|
const identity = await loadRemoteProjectIdentity();
|
|
@@ -3005,8 +3122,8 @@ async function resolveRemoteProject(options) {
|
|
|
3005
3122
|
// src/services/project/local-typecheck.ts
|
|
3006
3123
|
import { spawn as spawn2 } from "child_process";
|
|
3007
3124
|
import { lstat } from "fs/promises";
|
|
3008
|
-
import { createRequire } from "module";
|
|
3009
|
-
import
|
|
3125
|
+
import { createRequire as createRequire2 } from "module";
|
|
3126
|
+
import path2 from "path";
|
|
3010
3127
|
var TYPESCRIPT_BIN_PATH_SEGMENTS = [
|
|
3011
3128
|
"node_modules",
|
|
3012
3129
|
"typescript",
|
|
@@ -3016,17 +3133,17 @@ var TYPESCRIPT_BIN_PATH_SEGMENTS = [
|
|
|
3016
3133
|
var CLI_PACKAGE_TYPESCRIPT_CLI = resolveCliPackageTypescriptCli();
|
|
3017
3134
|
function resolveCliPackageTypescriptCli() {
|
|
3018
3135
|
try {
|
|
3019
|
-
const require2 =
|
|
3136
|
+
const require2 = createRequire2(import.meta.url);
|
|
3020
3137
|
return require2.resolve("typescript/bin/tsc");
|
|
3021
3138
|
} catch {
|
|
3022
3139
|
return null;
|
|
3023
3140
|
}
|
|
3024
3141
|
}
|
|
3025
3142
|
function getProjectNodeModules(projectRoot) {
|
|
3026
|
-
return
|
|
3143
|
+
return path2.join(projectRoot, "node_modules");
|
|
3027
3144
|
}
|
|
3028
3145
|
function getProjectTypescriptCli(projectRoot) {
|
|
3029
|
-
return
|
|
3146
|
+
return path2.join(projectRoot, ...TYPESCRIPT_BIN_PATH_SEGMENTS);
|
|
3030
3147
|
}
|
|
3031
3148
|
async function pathExists(targetPath) {
|
|
3032
3149
|
try {
|
|
@@ -3146,12 +3263,12 @@ async function runLocalTypecheck(projectRoot) {
|
|
|
3146
3263
|
// src/services/project/local-maintainer-registry.ts
|
|
3147
3264
|
import { spawn as spawn3 } from "child_process";
|
|
3148
3265
|
import { existsSync, readFileSync } from "fs";
|
|
3149
|
-
import
|
|
3266
|
+
import path3 from "path";
|
|
3150
3267
|
import { fileURLToPath } from "url";
|
|
3151
|
-
var MODULE_DIR =
|
|
3268
|
+
var MODULE_DIR = path3.dirname(fileURLToPath(import.meta.url));
|
|
3152
3269
|
function getCliPackageRoot() {
|
|
3153
3270
|
try {
|
|
3154
|
-
return
|
|
3271
|
+
return path3.join(
|
|
3155
3272
|
resolveCliRepoRoot(import.meta.url),
|
|
3156
3273
|
"apps",
|
|
3157
3274
|
"dreamboard-cli"
|
|
@@ -3163,7 +3280,7 @@ function getCliPackageRoot() {
|
|
|
3163
3280
|
function resolveInstalledCliPackageRoot(moduleDir) {
|
|
3164
3281
|
let current = moduleDir;
|
|
3165
3282
|
while (true) {
|
|
3166
|
-
const packageJsonPath =
|
|
3283
|
+
const packageJsonPath = path3.join(current, "package.json");
|
|
3167
3284
|
if (existsSync(packageJsonPath)) {
|
|
3168
3285
|
try {
|
|
3169
3286
|
const packageJson = JSON.parse(
|
|
@@ -3175,7 +3292,7 @@ function resolveInstalledCliPackageRoot(moduleDir) {
|
|
|
3175
3292
|
} catch {
|
|
3176
3293
|
}
|
|
3177
3294
|
}
|
|
3178
|
-
const parent =
|
|
3295
|
+
const parent = path3.dirname(current);
|
|
3179
3296
|
if (parent === current) {
|
|
3180
3297
|
return moduleDir;
|
|
3181
3298
|
}
|
|
@@ -3203,10 +3320,10 @@ function getScriptInvocation() {
|
|
|
3203
3320
|
};
|
|
3204
3321
|
}
|
|
3205
3322
|
function getLocalMaintainerScriptPath(cliPackageRoot) {
|
|
3206
|
-
return
|
|
3323
|
+
return path3.join(cliPackageRoot, "scripts", "local-maintainer-registry.ts");
|
|
3207
3324
|
}
|
|
3208
3325
|
function isInstalledCliPackageRoot(cliPackageRoot) {
|
|
3209
|
-
return cliPackageRoot.split(
|
|
3326
|
+
return cliPackageRoot.split(path3.sep).includes("node_modules");
|
|
3210
3327
|
}
|
|
3211
3328
|
function shouldSkipLocalMaintainerHelper() {
|
|
3212
3329
|
const cliPackageRoot = getCliPackageRoot();
|
|
@@ -3233,7 +3350,7 @@ function readInstalledCliLocalMaintainerSnapshot() {
|
|
|
3233
3350
|
if (!isInstalledCliPackageRoot(cliPackageRoot)) {
|
|
3234
3351
|
return null;
|
|
3235
3352
|
}
|
|
3236
|
-
const packageJsonPath =
|
|
3353
|
+
const packageJsonPath = path3.join(cliPackageRoot, "package.json");
|
|
3237
3354
|
if (!existsSync(packageJsonPath)) {
|
|
3238
3355
|
return null;
|
|
3239
3356
|
}
|
|
@@ -3341,7 +3458,7 @@ async function ensureLocalMaintainerSnapshot(apiBaseUrl) {
|
|
|
3341
3458
|
}
|
|
3342
3459
|
|
|
3343
3460
|
// src/services/project/dependency-portability.ts
|
|
3344
|
-
import
|
|
3461
|
+
import path4 from "path";
|
|
3345
3462
|
var DEPENDENCY_FIELDS = [
|
|
3346
3463
|
"dependencies",
|
|
3347
3464
|
"devDependencies",
|
|
@@ -3424,7 +3541,7 @@ async function assertReleaseEnvironmentPortableDependencies(options) {
|
|
|
3424
3541
|
}
|
|
3425
3542
|
async function readProjectPackageJson(projectRoot) {
|
|
3426
3543
|
return readJsonFile(
|
|
3427
|
-
|
|
3544
|
+
path4.join(projectRoot, "package.json")
|
|
3428
3545
|
);
|
|
3429
3546
|
}
|
|
3430
3547
|
function collectDreamboardPackageSpecifiers(packageJson) {
|
|
@@ -3523,7 +3640,7 @@ function isLocalRegistryUrl(rawUrl) {
|
|
|
3523
3640
|
}
|
|
3524
3641
|
}
|
|
3525
3642
|
async function readDreamboardRegistryFromNpmrc(projectRoot) {
|
|
3526
|
-
const npmrc = await readTextFileIfExists(
|
|
3643
|
+
const npmrc = await readTextFileIfExists(path4.join(projectRoot, ".npmrc"));
|
|
3527
3644
|
if (!npmrc) return void 0;
|
|
3528
3645
|
for (const line of npmrc.split(/\r?\n/)) {
|
|
3529
3646
|
const trimmed = line.trim();
|
|
@@ -3534,8 +3651,8 @@ async function readDreamboardRegistryFromNpmrc(projectRoot) {
|
|
|
3534
3651
|
}
|
|
3535
3652
|
|
|
3536
3653
|
// src/services/project/reducer-contract-preflight.ts
|
|
3537
|
-
import
|
|
3538
|
-
var GAME_CONTRACT_ENTRY_PATH =
|
|
3654
|
+
import path5 from "path";
|
|
3655
|
+
var GAME_CONTRACT_ENTRY_PATH = path5.join("app", "game-contract.ts");
|
|
3539
3656
|
function normalizeErrorMessage(error) {
|
|
3540
3657
|
const rawMessage = error instanceof Error ? error.message : String(error ?? "Unknown error");
|
|
3541
3658
|
return rawMessage.split("\n").map((line) => line.trim()).find(Boolean)?.replace(/^Error:\s*/u, "") ?? "Unknown error";
|
|
@@ -3544,7 +3661,7 @@ function isManifestScopedIdBrandingError(message) {
|
|
|
3544
3661
|
return message.includes("defineGameContract:") && message.includes("manifest-scoped") && (message.includes("uses a raw z.string()") || message.includes("uses z.array(z.string())"));
|
|
3545
3662
|
}
|
|
3546
3663
|
async function assertReducerContractPreflight(projectRoot) {
|
|
3547
|
-
const entryPath =
|
|
3664
|
+
const entryPath = path5.join(projectRoot, GAME_CONTRACT_ENTRY_PATH);
|
|
3548
3665
|
try {
|
|
3549
3666
|
await importTypeScriptModule(entryPath);
|
|
3550
3667
|
} catch (error) {
|
|
@@ -3570,11 +3687,11 @@ async function assertReducerContractPreflight(projectRoot) {
|
|
|
3570
3687
|
}
|
|
3571
3688
|
|
|
3572
3689
|
// src/services/project/reducer-bundle-preflight.ts
|
|
3573
|
-
import
|
|
3574
|
-
import { createRequire as
|
|
3575
|
-
import { pathToFileURL } from "url";
|
|
3690
|
+
import path6 from "path";
|
|
3691
|
+
import { createRequire as createRequire3 } from "module";
|
|
3692
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
3576
3693
|
globalThis.__DREAMBOARD_AUTHORING_WARNINGS__ = true;
|
|
3577
|
-
var REDUCER_BUNDLE_ENTRY_PATH =
|
|
3694
|
+
var REDUCER_BUNDLE_ENTRY_PATH = path6.join("app", "index.ts");
|
|
3578
3695
|
var PREFLIGHT_RNG_SEED = 1337;
|
|
3579
3696
|
function isStructuralPerPlayer(value) {
|
|
3580
3697
|
return typeof value === "object" && value !== null && value.__perPlayer === true && Array.isArray(value.entries);
|
|
@@ -3587,8 +3704,8 @@ function fallbackPerPlayerSchema(valueSchema, options) {
|
|
|
3587
3704
|
}).strict();
|
|
3588
3705
|
}
|
|
3589
3706
|
async function loadProjectReducerPreflightModules(projectRoot) {
|
|
3590
|
-
const requireFromProject =
|
|
3591
|
-
|
|
3707
|
+
const requireFromProject = createRequire3(
|
|
3708
|
+
path6.join(projectRoot, "package.json")
|
|
3592
3709
|
);
|
|
3593
3710
|
const reducerPath = requireFromProject.resolve(
|
|
3594
3711
|
"@dreamboard-games/sdk/reducer"
|
|
@@ -3597,8 +3714,8 @@ async function loadProjectReducerPreflightModules(projectRoot) {
|
|
|
3597
3714
|
"@dreamboard-games/sdk/reducer-contract"
|
|
3598
3715
|
);
|
|
3599
3716
|
const [reducerModule, reducerContractModule] = await Promise.all([
|
|
3600
|
-
import(
|
|
3601
|
-
import(
|
|
3717
|
+
import(pathToFileURL2(reducerPath).href),
|
|
3718
|
+
import(pathToFileURL2(reducerContractPath).href)
|
|
3602
3719
|
]);
|
|
3603
3720
|
if (typeof reducerModule.isPerPlayer !== "function" || typeof reducerModule.perPlayerSchema !== "function" || typeof reducerContractModule.materializeManifestTable !== "function") {
|
|
3604
3721
|
throw new Error(
|
|
@@ -3811,7 +3928,7 @@ async function runReducerBundleSmoke(options) {
|
|
|
3811
3928
|
if (scenarios.length === 0) {
|
|
3812
3929
|
return [];
|
|
3813
3930
|
}
|
|
3814
|
-
const entryPath =
|
|
3931
|
+
const entryPath = path6.join(projectRoot, REDUCER_BUNDLE_ENTRY_PATH);
|
|
3815
3932
|
let module;
|
|
3816
3933
|
try {
|
|
3817
3934
|
module = await importTypeScriptModule(
|
|
@@ -4063,9 +4180,9 @@ var dev_default = defineCommand({
|
|
|
4063
4180
|
env: parsedArgs.env ?? "local",
|
|
4064
4181
|
debug: parsedArgs.debug
|
|
4065
4182
|
});
|
|
4066
|
-
const devDir =
|
|
4183
|
+
const devDir = path7.join(projectRoot, PROJECT_DIR_NAME, "dev");
|
|
4067
4184
|
await ensureDir(devDir);
|
|
4068
|
-
const sessionFilePath =
|
|
4185
|
+
const sessionFilePath = path7.join(devDir, "session.json");
|
|
4069
4186
|
const requestedResumeSessionId = parsedArgs.resume?.trim() || null;
|
|
4070
4187
|
const requestedScenarioId = parsedArgs["from-scenario"]?.trim() || null;
|
|
4071
4188
|
if (requestedResumeSessionId && parsedArgs["new-session"]) {
|
|
@@ -4446,7 +4563,7 @@ async function resolveBackendVersionMetadata() {
|
|
|
4446
4563
|
}
|
|
4447
4564
|
async function readWorkspacePackageJson(projectRoot) {
|
|
4448
4565
|
try {
|
|
4449
|
-
const raw = await readTextFile(
|
|
4566
|
+
const raw = await readTextFile(path7.join(projectRoot, "package.json"));
|
|
4450
4567
|
const parsed = JSON.parse(raw);
|
|
4451
4568
|
return {
|
|
4452
4569
|
dependencies: Object.fromEntries(
|
|
@@ -4607,7 +4724,7 @@ var preview_default = defineCommand({
|
|
|
4607
4724
|
});
|
|
4608
4725
|
|
|
4609
4726
|
// src/commands/project-create.ts
|
|
4610
|
-
import
|
|
4727
|
+
import path8 from "path";
|
|
4611
4728
|
|
|
4612
4729
|
// src/services/git/workspace-origin.ts
|
|
4613
4730
|
var DREAMBOARD_GIT_CREDENTIAL_HELPER = "!dreamboard auth git-credential";
|
|
@@ -4777,7 +4894,7 @@ var project_create_default = defineCommand({
|
|
|
4777
4894
|
setupProfiles: []
|
|
4778
4895
|
};
|
|
4779
4896
|
consola.start("Scaffolding local workspace...");
|
|
4780
|
-
const targetDir =
|
|
4897
|
+
const targetDir = path8.resolve(process.cwd(), project.slug);
|
|
4781
4898
|
await materializeWorkspaceProject({
|
|
4782
4899
|
targetDir,
|
|
4783
4900
|
projectId,
|
|
@@ -4806,7 +4923,7 @@ var project_create_default = defineCommand({
|
|
|
4806
4923
|
|
|
4807
4924
|
// src/commands/project-clone.ts
|
|
4808
4925
|
import { mkdtemp, rename, rm } from "fs/promises";
|
|
4809
|
-
import
|
|
4926
|
+
import path9 from "path";
|
|
4810
4927
|
var DEFAULT_REPOSITORY_WAIT_TIMEOUT_MS2 = 12e4;
|
|
4811
4928
|
var DEFAULT_REPOSITORY_POLL_INTERVAL_MS2 = 1e3;
|
|
4812
4929
|
function parsePositiveIntegerFlag2(value, flagName, defaultValue) {
|
|
@@ -4872,7 +4989,7 @@ var project_clone_default = defineCommand({
|
|
|
4872
4989
|
requireAuth(config);
|
|
4873
4990
|
await configureClient(config);
|
|
4874
4991
|
const identity = await loadRemoteProjectIdentity();
|
|
4875
|
-
const targetDir =
|
|
4992
|
+
const targetDir = path9.resolve(process.cwd(), targetSlug);
|
|
4876
4993
|
if (await exists(targetDir)) {
|
|
4877
4994
|
throw new Error(`Target directory already exists: ${targetDir}`);
|
|
4878
4995
|
}
|
|
@@ -4896,9 +5013,9 @@ var project_clone_default = defineCommand({
|
|
|
4896
5013
|
error.name = "PROJECT_UNINITIALIZED";
|
|
4897
5014
|
throw error;
|
|
4898
5015
|
}
|
|
4899
|
-
const parentDir =
|
|
5016
|
+
const parentDir = path9.dirname(targetDir);
|
|
4900
5017
|
const tempDir = await mkdtemp(
|
|
4901
|
-
|
|
5018
|
+
path9.join(parentDir, `.${path9.basename(targetDir)}.dreamboard-clone-`)
|
|
4902
5019
|
);
|
|
4903
5020
|
let renamed = false;
|
|
4904
5021
|
try {
|
|
@@ -5336,56 +5453,148 @@ var release_default = defineCommand({
|
|
|
5336
5453
|
}
|
|
5337
5454
|
});
|
|
5338
5455
|
|
|
5339
|
-
// src/
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
function
|
|
5344
|
-
|
|
5456
|
+
// src/commands/test.ts
|
|
5457
|
+
var REDUCER_NATIVE_TEST_WORKSPACE_ERROR = "dreamboard test now requires a reducer-native workspace with app/game.ts, shared/generated/ui-contract.ts, test/bases/*.base.ts, and test/scenarios/*.scenario.ts. Legacy test/base-scenarios.json workspaces are no longer supported.";
|
|
5458
|
+
var NO_REDUCER_NATIVE_BASES_FOUND_ERROR = "No bases found under test/bases/*.base.ts";
|
|
5459
|
+
var NO_REDUCER_NATIVE_SCENARIOS_FOUND_ERROR = "No scenarios found under test/scenarios/*.scenario.ts";
|
|
5460
|
+
function resolveTestCommandPlan(args) {
|
|
5461
|
+
const updateSnapshots = Boolean(args["update-snapshots"]);
|
|
5462
|
+
return {
|
|
5463
|
+
updateSnapshots
|
|
5464
|
+
};
|
|
5345
5465
|
}
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
"Previous source preparation did not finish updating local scaffold files. Recreate or reclone the project workspace first."
|
|
5354
|
-
);
|
|
5355
|
-
}
|
|
5356
|
-
if (authoring.revisionDigest) {
|
|
5357
|
-
const compile = getProjectCompileState(projectConfig);
|
|
5358
|
-
const latestSuccess = (await findProjectCompiledResultsForRevision({
|
|
5359
|
-
projectId: projectConfig.projectId,
|
|
5360
|
-
revisionDigest: authoring.revisionDigest
|
|
5361
|
-
})).find((result) => result.success);
|
|
5362
|
-
const matchingLocalSuccess = compile.latestSuccessful?.revisionDigest === authoring.revisionDigest ? compile.latestSuccessful : void 0;
|
|
5363
|
-
const resolvedSuccess = latestSuccess ?? (matchingLocalSuccess?.resultId ? await getProjectCompiledResultSdk(
|
|
5364
|
-
projectConfig.projectId,
|
|
5365
|
-
matchingLocalSuccess.resultId
|
|
5366
|
-
) : void 0);
|
|
5367
|
-
if (!resolvedSuccess?.success) {
|
|
5466
|
+
function assertNoRemovedTestFlags(argv2) {
|
|
5467
|
+
for (let index = 0; index < argv2.length; index += 1) {
|
|
5468
|
+
const arg = argv2[index];
|
|
5469
|
+
if (arg === void 0) {
|
|
5470
|
+
continue;
|
|
5471
|
+
}
|
|
5472
|
+
if (arg === "--runner" || arg.startsWith("--runner=")) {
|
|
5368
5473
|
throw new Error(
|
|
5369
|
-
"
|
|
5474
|
+
"dreamboard test no longer supports --runner. The public CLI runs offline reducer tests only."
|
|
5370
5475
|
);
|
|
5371
5476
|
}
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
`Latest successful compile ${resolvedSuccess.id} belongs to ${resultRevisionDigest}, not ${authoring.revisionDigest}.`
|
|
5477
|
+
if (arg === "--commit" || arg.startsWith("--commit=")) {
|
|
5478
|
+
throw new Error(
|
|
5479
|
+
"dreamboard test no longer supports --commit. Use dreamboard verify/build/preview/release with --commit for pushed-commit workflows."
|
|
5376
5480
|
);
|
|
5377
5481
|
}
|
|
5378
|
-
consola.info(
|
|
5379
|
-
`Project summary:
|
|
5380
|
-
compiledResultId: ${resolvedSuccess.id}
|
|
5381
|
-
revisionDigest: ${authoring.revisionDigest}`
|
|
5382
|
-
);
|
|
5383
|
-
return resolvedSuccess;
|
|
5384
5482
|
}
|
|
5385
|
-
|
|
5386
|
-
|
|
5483
|
+
}
|
|
5484
|
+
function isStaleContractArtifactResult(result) {
|
|
5485
|
+
return result.errorCode === STALE_CONTRACT_ARTIFACT_CODE || (result.error ? isStaleContractArtifactMessage(result.error) : false);
|
|
5486
|
+
}
|
|
5487
|
+
function resolveTestRunExitCode(summary) {
|
|
5488
|
+
if (summary.failed === 0) {
|
|
5489
|
+
return 0;
|
|
5490
|
+
}
|
|
5491
|
+
return summary.results.some(
|
|
5492
|
+
(result) => !result.success && isStaleContractArtifactResult(result)
|
|
5493
|
+
) ? STALE_CONTRACT_ARTIFACT_EXIT_CODE : 1;
|
|
5494
|
+
}
|
|
5495
|
+
async function assertReducerNativeTestingWorkspace(projectRoot) {
|
|
5496
|
+
if (await isReducerNativeTestingWorkspace(projectRoot)) {
|
|
5497
|
+
return;
|
|
5498
|
+
}
|
|
5499
|
+
throw new Error(REDUCER_NATIVE_TEST_WORKSPACE_ERROR);
|
|
5500
|
+
}
|
|
5501
|
+
async function runTestCommand(args, deps = {}) {
|
|
5502
|
+
const parsedFlags = parseConfigFlags(args);
|
|
5503
|
+
const plan = resolveTestCommandPlan(args);
|
|
5504
|
+
const { projectRoot, projectConfig, config } = await (deps.resolveProjectContext ?? resolveProjectContext)(parsedFlags, {
|
|
5505
|
+
requireAuth: false
|
|
5506
|
+
});
|
|
5507
|
+
await (deps.assertPortableDependencies ?? assertReleaseEnvironmentPortableDependencies)({
|
|
5508
|
+
projectRoot,
|
|
5509
|
+
projectConfig,
|
|
5510
|
+
environment: config.environment
|
|
5511
|
+
});
|
|
5512
|
+
await (deps.assertTestingWorkspace ?? assertReducerNativeTestingWorkspace)(
|
|
5513
|
+
projectRoot
|
|
5387
5514
|
);
|
|
5515
|
+
const generated = await (deps.generateArtifacts ?? generateReducerNativeArtifacts)({
|
|
5516
|
+
projectRoot,
|
|
5517
|
+
scenarioPath: args.scenario,
|
|
5518
|
+
compiledResultId: projectConfig.compile?.latestSuccessful?.resultId,
|
|
5519
|
+
gameId: projectConfig.gameId,
|
|
5520
|
+
debug: Boolean(args.debug)
|
|
5521
|
+
});
|
|
5522
|
+
if (generated.bases.length === 0) {
|
|
5523
|
+
throw new Error(NO_REDUCER_NATIVE_BASES_FOUND_ERROR);
|
|
5524
|
+
}
|
|
5525
|
+
if (generated.scenarios.length === 0) {
|
|
5526
|
+
throw new Error(NO_REDUCER_NATIVE_SCENARIOS_FOUND_ERROR);
|
|
5527
|
+
}
|
|
5528
|
+
const summary = await (deps.runScenarios ?? runReducerNativeScenarios)({
|
|
5529
|
+
projectRoot,
|
|
5530
|
+
projectConfig,
|
|
5531
|
+
resolvedConfig: config,
|
|
5532
|
+
scenarioPath: args.scenario,
|
|
5533
|
+
compiledResultId: projectConfig.compile?.latestSuccessful?.resultId,
|
|
5534
|
+
gameId: projectConfig.gameId,
|
|
5535
|
+
debug: Boolean(args.debug),
|
|
5536
|
+
updateSnapshots: plan.updateSnapshots
|
|
5537
|
+
});
|
|
5538
|
+
printTestSummary(summary);
|
|
5388
5539
|
}
|
|
5540
|
+
function printTestSummary(summary) {
|
|
5541
|
+
for (const result of summary.results) {
|
|
5542
|
+
if (result.success) {
|
|
5543
|
+
consola.success(`PASS ${result.id}`);
|
|
5544
|
+
} else if (result.errorCode === STALE_CONTRACT_ARTIFACT_CODE && result.error) {
|
|
5545
|
+
consola.error(result.error);
|
|
5546
|
+
} else {
|
|
5547
|
+
consola.error(`FAIL ${result.id}: ${result.error ?? "Scenario failed"}`);
|
|
5548
|
+
}
|
|
5549
|
+
}
|
|
5550
|
+
consola.info(
|
|
5551
|
+
`Test summary: ${summary.passed} passed, ${summary.failed} failed.`
|
|
5552
|
+
);
|
|
5553
|
+
if (summary.failed > 0) {
|
|
5554
|
+
process.exitCode = resolveTestRunExitCode(summary);
|
|
5555
|
+
}
|
|
5556
|
+
}
|
|
5557
|
+
var runCommand2 = defineCommand({
|
|
5558
|
+
meta: {
|
|
5559
|
+
name: "run",
|
|
5560
|
+
description: "Run reducer-native scenarios from test/scenarios"
|
|
5561
|
+
},
|
|
5562
|
+
args: {
|
|
5563
|
+
scenario: {
|
|
5564
|
+
type: "string",
|
|
5565
|
+
description: "Optional scenario file path under test/scenarios"
|
|
5566
|
+
},
|
|
5567
|
+
debug: {
|
|
5568
|
+
type: "boolean",
|
|
5569
|
+
description: "Print full reducer-native validation details",
|
|
5570
|
+
default: false
|
|
5571
|
+
},
|
|
5572
|
+
"update-snapshots": {
|
|
5573
|
+
type: "boolean",
|
|
5574
|
+
description: "Refresh generated projection and scenario snapshots",
|
|
5575
|
+
default: false
|
|
5576
|
+
},
|
|
5577
|
+
...CONFIG_FLAG_ARGS
|
|
5578
|
+
},
|
|
5579
|
+
async run({ args }) {
|
|
5580
|
+
assertNoRemovedTestFlags(process.argv.slice(2));
|
|
5581
|
+
await runTestCommand(args);
|
|
5582
|
+
}
|
|
5583
|
+
});
|
|
5584
|
+
var test_default = defineCommand({
|
|
5585
|
+
meta: {
|
|
5586
|
+
name: "test",
|
|
5587
|
+
description: "Reducer-native test runner with typed bases and scenarios"
|
|
5588
|
+
},
|
|
5589
|
+
args: runCommand2.args,
|
|
5590
|
+
async run(context) {
|
|
5591
|
+
await runCommand2.run?.(context);
|
|
5592
|
+
}
|
|
5593
|
+
});
|
|
5594
|
+
|
|
5595
|
+
// src/commands/verify.ts
|
|
5596
|
+
import { execFile as execFile2 } from "child_process";
|
|
5597
|
+
import { promisify as promisify2 } from "util";
|
|
5389
5598
|
|
|
5390
5599
|
// src/services/verification/exact-commit-verifier.ts
|
|
5391
5600
|
import { spawn as spawn4 } from "child_process";
|
|
@@ -5393,7 +5602,7 @@ import { createHash as createHash2 } from "crypto";
|
|
|
5393
5602
|
import { existsSync as existsSync2 } from "fs";
|
|
5394
5603
|
import { mkdtemp as mkdtemp2, readFile, rm as rm2 } from "fs/promises";
|
|
5395
5604
|
import os from "os";
|
|
5396
|
-
import
|
|
5605
|
+
import path10 from "path";
|
|
5397
5606
|
var ALLOWED_DREAMBOARD_TRACKED_PATHS = /* @__PURE__ */ new Set([".dreamboard/project.json"]);
|
|
5398
5607
|
var CREDENTIAL_BASENAMES = /* @__PURE__ */ new Set([
|
|
5399
5608
|
".env",
|
|
@@ -5476,7 +5685,6 @@ async function runExactCommitVerification(options, deps = {}) {
|
|
|
5476
5685
|
projectRoot: worktreeRoot,
|
|
5477
5686
|
projectConfig,
|
|
5478
5687
|
resolvedConfig: options.config,
|
|
5479
|
-
runner: "reducer",
|
|
5480
5688
|
gameId: runtimeIdentity.gameId,
|
|
5481
5689
|
compiledResultId: runtimeIdentity.compiledResultId
|
|
5482
5690
|
});
|
|
@@ -5508,8 +5716,8 @@ async function runExactCommitVerification(options, deps = {}) {
|
|
|
5508
5716
|
}
|
|
5509
5717
|
async function withExactCommitWorktree(options, run, deps = {}) {
|
|
5510
5718
|
const git = deps.git ?? new SystemGit();
|
|
5511
|
-
const tempRoot = await deps.makeTempDir?.() ?? await mkdtemp2(
|
|
5512
|
-
const worktreeRoot =
|
|
5719
|
+
const tempRoot = await deps.makeTempDir?.() ?? await mkdtemp2(path10.join(os.tmpdir(), "dreamboard-verify-"));
|
|
5720
|
+
const worktreeRoot = path10.join(tempRoot, "worktree");
|
|
5513
5721
|
let worktreeCreated = false;
|
|
5514
5722
|
try {
|
|
5515
5723
|
await git.createDetachedWorktree(
|
|
@@ -5625,7 +5833,7 @@ async function assertExactCommitSourcePolicy(options) {
|
|
|
5625
5833
|
}
|
|
5626
5834
|
}
|
|
5627
5835
|
async function readGitTree(root, commitOid) {
|
|
5628
|
-
const { stdout } = await
|
|
5836
|
+
const { stdout } = await runCommand3(
|
|
5629
5837
|
"git",
|
|
5630
5838
|
["ls-tree", "-r", "-z", "--full-tree", commitOid],
|
|
5631
5839
|
root
|
|
@@ -5647,7 +5855,7 @@ function parseGitTree(output) {
|
|
|
5647
5855
|
});
|
|
5648
5856
|
}
|
|
5649
5857
|
async function runFrozenNoScriptsInstall(root) {
|
|
5650
|
-
await
|
|
5858
|
+
await runCommand3(
|
|
5651
5859
|
resolvePnpmCommand(),
|
|
5652
5860
|
[
|
|
5653
5861
|
"install",
|
|
@@ -5660,11 +5868,11 @@ async function runFrozenNoScriptsInstall(root) {
|
|
|
5660
5868
|
);
|
|
5661
5869
|
}
|
|
5662
5870
|
function resolvePnpmCommand() {
|
|
5663
|
-
const corepackPath =
|
|
5871
|
+
const corepackPath = path10.join(path10.dirname(process.execPath), "corepack");
|
|
5664
5872
|
return existsSync2(corepackPath) ? corepackPath : "pnpm";
|
|
5665
5873
|
}
|
|
5666
|
-
async function
|
|
5667
|
-
const finalArgs =
|
|
5874
|
+
async function runCommand3(command, args, cwd) {
|
|
5875
|
+
const finalArgs = path10.basename(command) === "corepack" ? ["pnpm", ...args] : [...args];
|
|
5668
5876
|
return new Promise((resolve, reject) => {
|
|
5669
5877
|
const child = spawn4(command, finalArgs, {
|
|
5670
5878
|
cwd,
|
|
@@ -5698,12 +5906,12 @@ async function runCommand2(command, args, cwd) {
|
|
|
5698
5906
|
});
|
|
5699
5907
|
}
|
|
5700
5908
|
async function readPolicyFileFromDisk(root, relativePath) {
|
|
5701
|
-
return readFile(
|
|
5909
|
+
return readFile(path10.join(root, relativePath));
|
|
5702
5910
|
}
|
|
5703
5911
|
function normalizeTreePath(filePath) {
|
|
5704
5912
|
if (filePath.includes("\\")) return null;
|
|
5705
|
-
const normalized =
|
|
5706
|
-
if (normalized === "." || normalized.startsWith("../") ||
|
|
5913
|
+
const normalized = path10.posix.normalize(filePath);
|
|
5914
|
+
if (normalized === "." || normalized.startsWith("../") || path10.posix.isAbsolute(normalized)) {
|
|
5707
5915
|
return null;
|
|
5708
5916
|
}
|
|
5709
5917
|
return normalized;
|
|
@@ -5715,275 +5923,16 @@ function isForbiddenDreamboardStatePath(filePath) {
|
|
|
5715
5923
|
return filePath.startsWith(".dreamboard/") && !ALLOWED_DREAMBOARD_TRACKED_PATHS.has(filePath);
|
|
5716
5924
|
}
|
|
5717
5925
|
function isCredentialLikePath(filePath) {
|
|
5718
|
-
const basename =
|
|
5926
|
+
const basename = path10.posix.basename(filePath);
|
|
5719
5927
|
if (CREDENTIAL_BASENAMES.has(basename)) return true;
|
|
5720
|
-
if (CREDENTIAL_EXTENSIONS.has(
|
|
5928
|
+
if (CREDENTIAL_EXTENSIONS.has(path10.posix.extname(basename))) return true;
|
|
5721
5929
|
return filePath.startsWith(".dreamboard-dev/deploy-secrets/");
|
|
5722
5930
|
}
|
|
5723
5931
|
function hasCredentialLikeContent(prefix) {
|
|
5724
5932
|
return /-----BEGIN [A-Z ]*PRIVATE KEY-----/.test(prefix) || /_authToken\s*=/i.test(prefix) || /(?:^|\n)\s*(?:npm_token|authToken|password|secret)\s*=/i.test(prefix);
|
|
5725
5933
|
}
|
|
5726
5934
|
|
|
5727
|
-
// src/commands/test.ts
|
|
5728
|
-
var REDUCER_NATIVE_TEST_WORKSPACE_ERROR = "dreamboard test now requires a reducer-native workspace with app/game.ts, shared/generated/ui-contract.ts, test/bases/*.base.ts, and test/scenarios/*.scenario.ts. Legacy test/base-scenarios.json workspaces are no longer supported.";
|
|
5729
|
-
var NO_REDUCER_NATIVE_BASES_FOUND_ERROR = "No bases found under test/bases/*.base.ts";
|
|
5730
|
-
var NO_REDUCER_NATIVE_SCENARIOS_FOUND_ERROR = "No scenarios found under test/scenarios/*.scenario.ts";
|
|
5731
|
-
function resolveRequestedRunner(value) {
|
|
5732
|
-
if (value == null || value === "") {
|
|
5733
|
-
return void 0;
|
|
5734
|
-
}
|
|
5735
|
-
if (value === "reducer" || value === "remote" || value === "browser") {
|
|
5736
|
-
return value;
|
|
5737
|
-
}
|
|
5738
|
-
throw new Error(
|
|
5739
|
-
`Unsupported test runner '${String(value)}'. Expected one of reducer, remote, browser.`
|
|
5740
|
-
);
|
|
5741
|
-
}
|
|
5742
|
-
function resolveTestCommandPlan(args) {
|
|
5743
|
-
const runner = resolveRequestedRunner(args.runner) ?? "reducer";
|
|
5744
|
-
const commit = typeof args.commit === "string" && args.commit.trim().length > 0 ? args.commit : void 0;
|
|
5745
|
-
const updateSnapshots = Boolean(args["update-snapshots"]);
|
|
5746
|
-
if (runner === "remote" && !commit) {
|
|
5747
|
-
throw new Error("dreamboard test --runner remote requires --commit <rev>.");
|
|
5748
|
-
}
|
|
5749
|
-
if (commit && runner !== "remote" && runner !== "browser") {
|
|
5750
|
-
throw new Error(
|
|
5751
|
-
"dreamboard test --commit is only valid with --runner remote or --runner browser."
|
|
5752
|
-
);
|
|
5753
|
-
}
|
|
5754
|
-
if (updateSnapshots && (runner === "remote" || commit)) {
|
|
5755
|
-
throw new Error(
|
|
5756
|
-
"dreamboard test --update-snapshots is only valid for current-worktree reducer or browser tests."
|
|
5757
|
-
);
|
|
5758
|
-
}
|
|
5759
|
-
return {
|
|
5760
|
-
runner,
|
|
5761
|
-
commit,
|
|
5762
|
-
updateSnapshots
|
|
5763
|
-
};
|
|
5764
|
-
}
|
|
5765
|
-
function isStaleContractArtifactResult(result) {
|
|
5766
|
-
return result.errorCode === STALE_CONTRACT_ARTIFACT_CODE || (result.error ? isStaleContractArtifactMessage(result.error) : false);
|
|
5767
|
-
}
|
|
5768
|
-
function resolveTestRunExitCode(summary) {
|
|
5769
|
-
if (summary.failed === 0) {
|
|
5770
|
-
return 0;
|
|
5771
|
-
}
|
|
5772
|
-
return summary.results.some(
|
|
5773
|
-
(result) => !result.success && isStaleContractArtifactResult(result)
|
|
5774
|
-
) ? STALE_CONTRACT_ARTIFACT_EXIT_CODE : 1;
|
|
5775
|
-
}
|
|
5776
|
-
async function assertReducerNativeTestingWorkspace(projectRoot) {
|
|
5777
|
-
if (await isReducerNativeTestingWorkspace(projectRoot)) {
|
|
5778
|
-
return;
|
|
5779
|
-
}
|
|
5780
|
-
throw new Error(REDUCER_NATIVE_TEST_WORKSPACE_ERROR);
|
|
5781
|
-
}
|
|
5782
|
-
function assertRemoteCommitReady(status) {
|
|
5783
|
-
if (!status.source.observed) {
|
|
5784
|
-
throw new Error(
|
|
5785
|
-
`Remote commit tests require pushed commit ${status.commitOid}. Push the commit, then run dreamboard project status --commit ${status.commitOid} --wait.`
|
|
5786
|
-
);
|
|
5787
|
-
}
|
|
5788
|
-
if (status.source.validationStatus !== "SUCCEEDED") {
|
|
5789
|
-
throw new Error(
|
|
5790
|
-
`Remote commit tests require source validation to succeed for ${status.commitOid}; current status is ${status.source.validationStatus ?? "UNKNOWN"}.`
|
|
5791
|
-
);
|
|
5792
|
-
}
|
|
5793
|
-
const revisionDigest = status.gameRevision.revisionDigest;
|
|
5794
|
-
if (!revisionDigest) {
|
|
5795
|
-
throw new Error(
|
|
5796
|
-
`Remote commit tests require a materialized game revision for ${status.commitOid}. Run dreamboard project status --commit ${status.commitOid} --wait and retry after validation completes.`
|
|
5797
|
-
);
|
|
5798
|
-
}
|
|
5799
|
-
return revisionDigest;
|
|
5800
|
-
}
|
|
5801
|
-
async function resolveRemoteCommitCompiledResult(options) {
|
|
5802
|
-
const revisionDigest = assertRemoteCommitReady(options.status);
|
|
5803
|
-
const previewBuild = options.status.builds.find(
|
|
5804
|
-
(build) => build.targetProfile === "preview" && build.compiledArtifactStatus === "SUCCEEDED" && typeof build.compiledArtifactId === "string" && build.compiledArtifactId.length > 0
|
|
5805
|
-
);
|
|
5806
|
-
if (previewBuild?.compiledArtifactId) {
|
|
5807
|
-
return { id: previewBuild.compiledArtifactId };
|
|
5808
|
-
}
|
|
5809
|
-
const compiledResults = await (options.findCompiledResultsForRevision ?? findProjectCompiledResultsForRevision)({
|
|
5810
|
-
projectId: options.projectId,
|
|
5811
|
-
revisionDigest
|
|
5812
|
-
});
|
|
5813
|
-
const compiledResult = compiledResults.find((result) => result.success);
|
|
5814
|
-
if (!compiledResult) {
|
|
5815
|
-
throw new Error(
|
|
5816
|
-
`Remote commit tests require a successful compiled result for commit ${options.status.commitOid} (revision ${revisionDigest}). Run dreamboard build --commit ${options.status.commitOid}, wait for it to succeed, and retry.`
|
|
5817
|
-
);
|
|
5818
|
-
}
|
|
5819
|
-
return compiledResult;
|
|
5820
|
-
}
|
|
5821
|
-
async function resolveReducerNativeRuntimeIdentity(options) {
|
|
5822
|
-
if (options.useRemoteRuntime || options.runner === "remote") {
|
|
5823
|
-
const latestCompiledResult = await resolveLatestCompiledResult(
|
|
5824
|
-
options.projectRoot,
|
|
5825
|
-
options.projectConfig
|
|
5826
|
-
);
|
|
5827
|
-
return {
|
|
5828
|
-
gameId: options.projectConfig.gameId,
|
|
5829
|
-
compiledResultId: latestCompiledResult.id
|
|
5830
|
-
};
|
|
5831
|
-
}
|
|
5832
|
-
return {
|
|
5833
|
-
gameId: options.projectConfig.gameId,
|
|
5834
|
-
compiledResultId: options.projectConfig.compile?.latestSuccessful?.resultId
|
|
5835
|
-
};
|
|
5836
|
-
}
|
|
5837
|
-
async function runTestCommand(args, deps = {}) {
|
|
5838
|
-
const parsedFlags = parseConfigFlags(args);
|
|
5839
|
-
const plan = resolveTestCommandPlan(args);
|
|
5840
|
-
const useRemoteRuntime = shouldUseRemoteTestRuntime(parsedFlags.env);
|
|
5841
|
-
if (plan.commit) {
|
|
5842
|
-
const { projectRoot: projectRoot2, config: config2, commitOid } = await (deps.resolveCommitScopedProjectContext ?? resolveCommitScopedProjectContext)(parsedFlags, plan.commit, { requireAuth: true });
|
|
5843
|
-
await (deps.withExactCommitWorktree ?? withExactCommitWorktree)(
|
|
5844
|
-
{
|
|
5845
|
-
projectRoot: projectRoot2,
|
|
5846
|
-
commitOid
|
|
5847
|
-
},
|
|
5848
|
-
async (worktreeRoot) => {
|
|
5849
|
-
const prepared = await (deps.prepareExactCommitWorkspace ?? prepareExactCommitWorkspace)({
|
|
5850
|
-
worktreeRoot
|
|
5851
|
-
});
|
|
5852
|
-
const status = await (deps.getProjectCommitStatus ?? getProjectCommitStatusSdk)({
|
|
5853
|
-
projectId: prepared.projectConfig.projectId,
|
|
5854
|
-
commitOid
|
|
5855
|
-
});
|
|
5856
|
-
const compiledResult = await resolveRemoteCommitCompiledResult({
|
|
5857
|
-
projectId: prepared.projectConfig.projectId,
|
|
5858
|
-
status,
|
|
5859
|
-
findCompiledResultsForRevision: deps.findCompiledResultsForRevision
|
|
5860
|
-
});
|
|
5861
|
-
await (deps.assertTestingWorkspace ?? assertReducerNativeTestingWorkspace)(worktreeRoot);
|
|
5862
|
-
const generated = await (deps.generateArtifacts ?? generateReducerNativeArtifacts)({
|
|
5863
|
-
projectRoot: worktreeRoot,
|
|
5864
|
-
scenarioPath: args.scenario,
|
|
5865
|
-
compiledResultId: compiledResult.id,
|
|
5866
|
-
gameId: prepared.projectConfig.gameId,
|
|
5867
|
-
debug: Boolean(args.debug)
|
|
5868
|
-
});
|
|
5869
|
-
if (generated.bases.length === 0) {
|
|
5870
|
-
throw new Error(NO_REDUCER_NATIVE_BASES_FOUND_ERROR);
|
|
5871
|
-
}
|
|
5872
|
-
if (generated.scenarios.length === 0) {
|
|
5873
|
-
throw new Error(NO_REDUCER_NATIVE_SCENARIOS_FOUND_ERROR);
|
|
5874
|
-
}
|
|
5875
|
-
const summary2 = await (deps.runScenarios ?? runReducerNativeScenarios)({
|
|
5876
|
-
projectRoot: worktreeRoot,
|
|
5877
|
-
projectConfig: prepared.projectConfig,
|
|
5878
|
-
resolvedConfig: config2,
|
|
5879
|
-
runner: plan.runner,
|
|
5880
|
-
scenarioPath: args.scenario,
|
|
5881
|
-
compiledResultId: compiledResult.id,
|
|
5882
|
-
gameId: prepared.projectConfig.gameId,
|
|
5883
|
-
debug: Boolean(args.debug),
|
|
5884
|
-
updateSnapshots: false
|
|
5885
|
-
});
|
|
5886
|
-
printTestSummary(summary2);
|
|
5887
|
-
}
|
|
5888
|
-
);
|
|
5889
|
-
return;
|
|
5890
|
-
}
|
|
5891
|
-
const { projectRoot, projectConfig, config } = await (deps.resolveProjectContext ?? resolveProjectContext)(parsedFlags, {
|
|
5892
|
-
requireAuth: useRemoteRuntime || plan.runner === "remote"
|
|
5893
|
-
});
|
|
5894
|
-
await (deps.assertPortableDependencies ?? assertReleaseEnvironmentPortableDependencies)({
|
|
5895
|
-
projectRoot,
|
|
5896
|
-
projectConfig,
|
|
5897
|
-
environment: config.environment
|
|
5898
|
-
});
|
|
5899
|
-
await (deps.assertTestingWorkspace ?? assertReducerNativeTestingWorkspace)(
|
|
5900
|
-
projectRoot
|
|
5901
|
-
);
|
|
5902
|
-
const runtimeIdentity = await (deps.resolveRuntimeIdentity ?? resolveReducerNativeRuntimeIdentity)({
|
|
5903
|
-
projectRoot,
|
|
5904
|
-
projectConfig,
|
|
5905
|
-
useRemoteRuntime,
|
|
5906
|
-
runner: plan.runner
|
|
5907
|
-
});
|
|
5908
|
-
const summary = await (deps.runScenarios ?? runReducerNativeScenarios)({
|
|
5909
|
-
projectRoot,
|
|
5910
|
-
projectConfig,
|
|
5911
|
-
resolvedConfig: config,
|
|
5912
|
-
runner: plan.runner,
|
|
5913
|
-
scenarioPath: args.scenario,
|
|
5914
|
-
compiledResultId: runtimeIdentity.compiledResultId,
|
|
5915
|
-
gameId: runtimeIdentity.gameId,
|
|
5916
|
-
debug: Boolean(args.debug),
|
|
5917
|
-
updateSnapshots: plan.updateSnapshots
|
|
5918
|
-
});
|
|
5919
|
-
printTestSummary(summary);
|
|
5920
|
-
}
|
|
5921
|
-
function printTestSummary(summary) {
|
|
5922
|
-
for (const result of summary.results) {
|
|
5923
|
-
if (result.success) {
|
|
5924
|
-
consola.success(`PASS ${result.id}`);
|
|
5925
|
-
} else if (result.errorCode === STALE_CONTRACT_ARTIFACT_CODE && result.error) {
|
|
5926
|
-
consola.error(result.error);
|
|
5927
|
-
} else {
|
|
5928
|
-
consola.error(`FAIL ${result.id}: ${result.error ?? "Scenario failed"}`);
|
|
5929
|
-
}
|
|
5930
|
-
}
|
|
5931
|
-
consola.info(
|
|
5932
|
-
`Test summary: ${summary.passed} passed, ${summary.failed} failed.`
|
|
5933
|
-
);
|
|
5934
|
-
if (summary.failed > 0) {
|
|
5935
|
-
process.exitCode = resolveTestRunExitCode(summary);
|
|
5936
|
-
}
|
|
5937
|
-
}
|
|
5938
|
-
var runCommand3 = defineCommand({
|
|
5939
|
-
meta: {
|
|
5940
|
-
name: "run",
|
|
5941
|
-
description: "Run reducer-native scenarios from test/scenarios"
|
|
5942
|
-
},
|
|
5943
|
-
args: {
|
|
5944
|
-
scenario: {
|
|
5945
|
-
type: "string",
|
|
5946
|
-
description: "Optional scenario file path under test/scenarios"
|
|
5947
|
-
},
|
|
5948
|
-
debug: {
|
|
5949
|
-
type: "boolean",
|
|
5950
|
-
description: "Print full reducer-native validation details",
|
|
5951
|
-
default: false
|
|
5952
|
-
},
|
|
5953
|
-
"update-snapshots": {
|
|
5954
|
-
type: "boolean",
|
|
5955
|
-
description: "Refresh generated projection and scenario snapshots",
|
|
5956
|
-
default: false
|
|
5957
|
-
},
|
|
5958
|
-
runner: {
|
|
5959
|
-
type: "string",
|
|
5960
|
-
valueHint: "reducer|remote|browser",
|
|
5961
|
-
description: "Scenario runner: reducer (in-process, default), remote (live sessions against the configured backend), or browser (real dev-host browser flow)."
|
|
5962
|
-
},
|
|
5963
|
-
commit: {
|
|
5964
|
-
type: "string",
|
|
5965
|
-
description: "Git revision to resolve once before remote testing"
|
|
5966
|
-
},
|
|
5967
|
-
...CONFIG_FLAG_ARGS
|
|
5968
|
-
},
|
|
5969
|
-
async run({ args }) {
|
|
5970
|
-
await runTestCommand(args);
|
|
5971
|
-
}
|
|
5972
|
-
});
|
|
5973
|
-
var test_default = defineCommand({
|
|
5974
|
-
meta: {
|
|
5975
|
-
name: "test",
|
|
5976
|
-
description: "Reducer-native test runner with typed bases and scenarios"
|
|
5977
|
-
},
|
|
5978
|
-
args: runCommand3.args,
|
|
5979
|
-
async run(context) {
|
|
5980
|
-
await runCommand3.run?.(context);
|
|
5981
|
-
}
|
|
5982
|
-
});
|
|
5983
|
-
|
|
5984
5935
|
// src/commands/verify.ts
|
|
5985
|
-
import { execFile as execFile2 } from "child_process";
|
|
5986
|
-
import { promisify as promisify2 } from "util";
|
|
5987
5936
|
var execFileAsync2 = promisify2(execFile2);
|
|
5988
5937
|
async function findGitRoot() {
|
|
5989
5938
|
const { stdout } = await execFileAsync2(
|
|
@@ -6067,8 +6016,8 @@ function consumeMachineOutputMode(argv2) {
|
|
|
6067
6016
|
runId: crypto3.randomUUID()
|
|
6068
6017
|
} : null;
|
|
6069
6018
|
}
|
|
6070
|
-
function commandPathToId(
|
|
6071
|
-
const [first, second] =
|
|
6019
|
+
function commandPathToId(path11) {
|
|
6020
|
+
const [first, second] = path11;
|
|
6072
6021
|
if (first === "auth") {
|
|
6073
6022
|
if (second === "git-credential") return "auth.git_credential";
|
|
6074
6023
|
if (second === "status") return "auth.status";
|
|
@@ -6333,7 +6282,7 @@ function runDreamboardCli(internalSubCommands = {}) {
|
|
|
6333
6282
|
const main = defineCommand({
|
|
6334
6283
|
meta: {
|
|
6335
6284
|
name: "dreamboard",
|
|
6336
|
-
version: "0.1.30-alpha.
|
|
6285
|
+
version: "0.1.30-alpha.30",
|
|
6337
6286
|
description: "Dreamboard CLI \u2014 game development platform"
|
|
6338
6287
|
},
|
|
6339
6288
|
subCommands
|