dreamboard 0.1.4 → 0.1.6
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 +0 -44
- package/dist/index.js +320 -63
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -529,6 +529,11 @@ var createCompiledResult = (options) => (options.client ?? client).post({
|
|
|
529
529
|
...options.headers
|
|
530
530
|
}
|
|
531
531
|
});
|
|
532
|
+
var getCompiledResult = (options) => (options.client ?? client).get({
|
|
533
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
534
|
+
url: "/api/games/{gameId}/compiled-results/{compiledResultId}",
|
|
535
|
+
...options
|
|
536
|
+
});
|
|
532
537
|
var getGameSources = (options) => (options.client ?? client).get({
|
|
533
538
|
security: [{ scheme: "bearer", type: "http" }],
|
|
534
539
|
url: "/api/games/{gameId}/sources",
|
|
@@ -609,6 +614,11 @@ var submitAction = (options) => (options.client ?? client).post({
|
|
|
609
614
|
...options.headers
|
|
610
615
|
}
|
|
611
616
|
});
|
|
617
|
+
var getJob = (options) => (options.client ?? client).get({
|
|
618
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
619
|
+
url: "/api/jobs/{jobId}",
|
|
620
|
+
...options
|
|
621
|
+
});
|
|
612
622
|
|
|
613
623
|
// src/config/global-config.ts
|
|
614
624
|
import os from "os";
|
|
@@ -1513,10 +1523,10 @@ function mergeDefs(...defs) {
|
|
|
1513
1523
|
function cloneDef(schema) {
|
|
1514
1524
|
return mergeDefs(schema._zod.def);
|
|
1515
1525
|
}
|
|
1516
|
-
function getElementAtPath(obj,
|
|
1517
|
-
if (!
|
|
1526
|
+
function getElementAtPath(obj, path15) {
|
|
1527
|
+
if (!path15)
|
|
1518
1528
|
return obj;
|
|
1519
|
-
return
|
|
1529
|
+
return path15.reduce((acc, key) => acc?.[key], obj);
|
|
1520
1530
|
}
|
|
1521
1531
|
function promiseAllObject(promisesObj) {
|
|
1522
1532
|
const keys = Object.keys(promisesObj);
|
|
@@ -1899,11 +1909,11 @@ function aborted(x, startIndex = 0) {
|
|
|
1899
1909
|
}
|
|
1900
1910
|
return false;
|
|
1901
1911
|
}
|
|
1902
|
-
function prefixIssues(
|
|
1912
|
+
function prefixIssues(path15, issues) {
|
|
1903
1913
|
return issues.map((iss) => {
|
|
1904
1914
|
var _a2;
|
|
1905
1915
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
1906
|
-
iss.path.unshift(
|
|
1916
|
+
iss.path.unshift(path15);
|
|
1907
1917
|
return iss;
|
|
1908
1918
|
});
|
|
1909
1919
|
}
|
|
@@ -2086,7 +2096,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
|
|
|
2086
2096
|
}
|
|
2087
2097
|
function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
2088
2098
|
const result = { errors: [] };
|
|
2089
|
-
const processError = (error49,
|
|
2099
|
+
const processError = (error49, path15 = []) => {
|
|
2090
2100
|
var _a2, _b;
|
|
2091
2101
|
for (const issue2 of error49.issues) {
|
|
2092
2102
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -2096,7 +2106,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
2096
2106
|
} else if (issue2.code === "invalid_element") {
|
|
2097
2107
|
processError({ issues: issue2.issues }, issue2.path);
|
|
2098
2108
|
} else {
|
|
2099
|
-
const fullpath = [...
|
|
2109
|
+
const fullpath = [...path15, ...issue2.path];
|
|
2100
2110
|
if (fullpath.length === 0) {
|
|
2101
2111
|
result.errors.push(mapper(issue2));
|
|
2102
2112
|
continue;
|
|
@@ -2128,8 +2138,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
|
|
|
2128
2138
|
}
|
|
2129
2139
|
function toDotPath(_path) {
|
|
2130
2140
|
const segs = [];
|
|
2131
|
-
const
|
|
2132
|
-
for (const seg of
|
|
2141
|
+
const path15 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
2142
|
+
for (const seg of path15) {
|
|
2133
2143
|
if (typeof seg === "number")
|
|
2134
2144
|
segs.push(`[${seg}]`);
|
|
2135
2145
|
else if (typeof seg === "symbol")
|
|
@@ -14106,13 +14116,13 @@ function resolveRef(ref, ctx) {
|
|
|
14106
14116
|
if (!ref.startsWith("#")) {
|
|
14107
14117
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14108
14118
|
}
|
|
14109
|
-
const
|
|
14110
|
-
if (
|
|
14119
|
+
const path15 = ref.slice(1).split("/").filter(Boolean);
|
|
14120
|
+
if (path15.length === 0) {
|
|
14111
14121
|
return ctx.rootSchema;
|
|
14112
14122
|
}
|
|
14113
14123
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14114
|
-
if (
|
|
14115
|
-
const key =
|
|
14124
|
+
if (path15[0] === defsKey) {
|
|
14125
|
+
const key = path15[1];
|
|
14116
14126
|
if (!key || !ctx.defs[key]) {
|
|
14117
14127
|
throw new Error(`Reference not found: ${ref}`);
|
|
14118
14128
|
}
|
|
@@ -14543,7 +14553,8 @@ var pullCommandArgsSchema = configFlagsSchema.extend({
|
|
|
14543
14553
|
});
|
|
14544
14554
|
var pushCommandArgsSchema = configFlagsSchema.extend({
|
|
14545
14555
|
force: external_exports.boolean().default(false),
|
|
14546
|
-
debug: external_exports.boolean().default(false)
|
|
14556
|
+
debug: external_exports.boolean().default(false),
|
|
14557
|
+
"skip-local-check": external_exports.boolean().default(false)
|
|
14547
14558
|
});
|
|
14548
14559
|
var statusCommandArgsSchema = configFlagsSchema.extend({
|
|
14549
14560
|
json: external_exports.boolean().default(false)
|
|
@@ -14702,6 +14713,61 @@ async function findLatestSuccessfulCompiledResult(gameId) {
|
|
|
14702
14713
|
});
|
|
14703
14714
|
return data ?? null;
|
|
14704
14715
|
}
|
|
14716
|
+
async function getCompiledResultSdk(gameId, compiledResultId) {
|
|
14717
|
+
const { data, error: error48, response } = await getCompiledResult({
|
|
14718
|
+
path: {
|
|
14719
|
+
gameId,
|
|
14720
|
+
compiledResultId
|
|
14721
|
+
}
|
|
14722
|
+
});
|
|
14723
|
+
if (error48 || !data) {
|
|
14724
|
+
throw new Error(
|
|
14725
|
+
formatApiError(error48, response, "Failed to fetch compiled result")
|
|
14726
|
+
);
|
|
14727
|
+
}
|
|
14728
|
+
return data;
|
|
14729
|
+
}
|
|
14730
|
+
async function waitForCompiledResultJobSdk(options) {
|
|
14731
|
+
const { gameId, jobId, onProgress } = options;
|
|
14732
|
+
let previousTransitionKey = null;
|
|
14733
|
+
for (let attempt = 0; attempt < 180; attempt += 1) {
|
|
14734
|
+
const {
|
|
14735
|
+
data: job,
|
|
14736
|
+
error: error48,
|
|
14737
|
+
response
|
|
14738
|
+
} = await getJob({
|
|
14739
|
+
path: { jobId }
|
|
14740
|
+
});
|
|
14741
|
+
if (error48 || !job) {
|
|
14742
|
+
throw new Error(formatApiError(error48, response, "Failed to get job"));
|
|
14743
|
+
}
|
|
14744
|
+
const transitionKey = `${job.status}:${job.phase ?? ""}`;
|
|
14745
|
+
if (transitionKey !== previousTransitionKey) {
|
|
14746
|
+
previousTransitionKey = transitionKey;
|
|
14747
|
+
onProgress?.(job);
|
|
14748
|
+
}
|
|
14749
|
+
if (job.status === "COMPLETED" || job.status === "FAILED") {
|
|
14750
|
+
const compiledResultId = job.createdCompiledResultId ?? job.createdAppScriptId;
|
|
14751
|
+
if (!compiledResultId) {
|
|
14752
|
+
throw new Error(
|
|
14753
|
+
job.errorMessage ?? `Compile job ${jobId} finished without a result.`
|
|
14754
|
+
);
|
|
14755
|
+
}
|
|
14756
|
+
const compiledResult = await getCompiledResultSdk(
|
|
14757
|
+
gameId,
|
|
14758
|
+
compiledResultId
|
|
14759
|
+
);
|
|
14760
|
+
return { job, compiledResult };
|
|
14761
|
+
}
|
|
14762
|
+
if (job.status === "CANCELLED" || job.status === "INTERRUPTED") {
|
|
14763
|
+
throw new Error(
|
|
14764
|
+
job.errorMessage ?? `Compile job ${jobId} ${job.status.toLowerCase()}.`
|
|
14765
|
+
);
|
|
14766
|
+
}
|
|
14767
|
+
await sleep(1e3);
|
|
14768
|
+
}
|
|
14769
|
+
throw new Error(`Compile job ${jobId} did not complete in time.`);
|
|
14770
|
+
}
|
|
14705
14771
|
|
|
14706
14772
|
// src/services/api/game-api.ts
|
|
14707
14773
|
async function tryGetGameBySlug(slug, opts) {
|
|
@@ -14849,7 +14915,7 @@ async function createCompiledResultSdk(options) {
|
|
|
14849
14915
|
});
|
|
14850
14916
|
if (error48 || !data) {
|
|
14851
14917
|
throw new Error(
|
|
14852
|
-
formatApiError(error48, response, "Failed to create
|
|
14918
|
+
formatApiError(error48, response, "Failed to create compile job")
|
|
14853
14919
|
);
|
|
14854
14920
|
}
|
|
14855
14921
|
return data;
|
|
@@ -22313,6 +22379,149 @@ var clone_default = defineCommand({
|
|
|
22313
22379
|
}
|
|
22314
22380
|
});
|
|
22315
22381
|
|
|
22382
|
+
// src/services/project/local-typecheck.ts
|
|
22383
|
+
import { spawn } from "child_process";
|
|
22384
|
+
import { lstat, mkdir, symlink } from "fs/promises";
|
|
22385
|
+
import path8 from "path";
|
|
22386
|
+
import { fileURLToPath } from "url";
|
|
22387
|
+
var MODULE_DIR = path8.dirname(fileURLToPath(import.meta.url));
|
|
22388
|
+
var REPO_ROOT = path8.resolve(MODULE_DIR, "../../../../..");
|
|
22389
|
+
var WORKSPACE_NODE_MODULES = path8.join(REPO_ROOT, "node_modules");
|
|
22390
|
+
var UI_SDK_NODE_MODULES = path8.join(
|
|
22391
|
+
REPO_ROOT,
|
|
22392
|
+
"packages",
|
|
22393
|
+
"ui-sdk",
|
|
22394
|
+
"node_modules"
|
|
22395
|
+
);
|
|
22396
|
+
var TYPESCRIPT_CLI = path8.join(
|
|
22397
|
+
WORKSPACE_NODE_MODULES,
|
|
22398
|
+
"typescript",
|
|
22399
|
+
"bin",
|
|
22400
|
+
"tsc"
|
|
22401
|
+
);
|
|
22402
|
+
async function pathExists(targetPath) {
|
|
22403
|
+
try {
|
|
22404
|
+
await lstat(targetPath);
|
|
22405
|
+
return true;
|
|
22406
|
+
} catch {
|
|
22407
|
+
return false;
|
|
22408
|
+
}
|
|
22409
|
+
}
|
|
22410
|
+
async function ensureSymlink(targetPath, linkPath) {
|
|
22411
|
+
if (await pathExists(linkPath)) {
|
|
22412
|
+
return;
|
|
22413
|
+
}
|
|
22414
|
+
await mkdir(path8.dirname(linkPath), { recursive: true });
|
|
22415
|
+
await symlink(
|
|
22416
|
+
targetPath,
|
|
22417
|
+
linkPath,
|
|
22418
|
+
process.platform === "win32" ? "junction" : "dir"
|
|
22419
|
+
);
|
|
22420
|
+
}
|
|
22421
|
+
async function ensureTypecheckDependencies(projectRoot) {
|
|
22422
|
+
if (!await pathExists(WORKSPACE_NODE_MODULES)) {
|
|
22423
|
+
return `Skipping local typecheck: workspace dependencies are not installed at ${WORKSPACE_NODE_MODULES}.`;
|
|
22424
|
+
}
|
|
22425
|
+
if (!await pathExists(UI_SDK_NODE_MODULES)) {
|
|
22426
|
+
return `Skipping local typecheck: ui-sdk dependencies are not installed at ${UI_SDK_NODE_MODULES}.`;
|
|
22427
|
+
}
|
|
22428
|
+
await ensureSymlink(
|
|
22429
|
+
WORKSPACE_NODE_MODULES,
|
|
22430
|
+
path8.join(projectRoot, "node_modules")
|
|
22431
|
+
);
|
|
22432
|
+
await ensureSymlink(
|
|
22433
|
+
UI_SDK_NODE_MODULES,
|
|
22434
|
+
path8.join(projectRoot, "ui", "node_modules")
|
|
22435
|
+
);
|
|
22436
|
+
return null;
|
|
22437
|
+
}
|
|
22438
|
+
async function resolveTypecheckRunner() {
|
|
22439
|
+
if (await pathExists(TYPESCRIPT_CLI)) {
|
|
22440
|
+
return {
|
|
22441
|
+
command: process.execPath,
|
|
22442
|
+
argsPrefix: [TYPESCRIPT_CLI]
|
|
22443
|
+
};
|
|
22444
|
+
}
|
|
22445
|
+
const globalTscAvailable = await new Promise((resolve) => {
|
|
22446
|
+
const child = spawn("tsc", ["--version"], {
|
|
22447
|
+
env: process.env,
|
|
22448
|
+
stdio: "ignore"
|
|
22449
|
+
});
|
|
22450
|
+
child.on("error", () => {
|
|
22451
|
+
resolve(false);
|
|
22452
|
+
});
|
|
22453
|
+
child.on("close", (code) => {
|
|
22454
|
+
resolve(code === 0);
|
|
22455
|
+
});
|
|
22456
|
+
});
|
|
22457
|
+
if (!globalTscAvailable) {
|
|
22458
|
+
return null;
|
|
22459
|
+
}
|
|
22460
|
+
return {
|
|
22461
|
+
command: "tsc",
|
|
22462
|
+
argsPrefix: []
|
|
22463
|
+
};
|
|
22464
|
+
}
|
|
22465
|
+
async function runTypecheckProject(runner, projectRoot, projectPath) {
|
|
22466
|
+
return new Promise((resolve, reject) => {
|
|
22467
|
+
const child = spawn(
|
|
22468
|
+
runner.command,
|
|
22469
|
+
[...runner.argsPrefix, "--noEmit", "-p", projectPath],
|
|
22470
|
+
{
|
|
22471
|
+
cwd: projectRoot,
|
|
22472
|
+
env: process.env,
|
|
22473
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
22474
|
+
}
|
|
22475
|
+
);
|
|
22476
|
+
let stdout = "";
|
|
22477
|
+
let stderr = "";
|
|
22478
|
+
child.stdout.on("data", (chunk) => {
|
|
22479
|
+
stdout += chunk.toString();
|
|
22480
|
+
});
|
|
22481
|
+
child.stderr.on("data", (chunk) => {
|
|
22482
|
+
stderr += chunk.toString();
|
|
22483
|
+
});
|
|
22484
|
+
child.on("error", (error48) => {
|
|
22485
|
+
reject(new Error(`Failed to start local typecheck. ${error48.message}`));
|
|
22486
|
+
});
|
|
22487
|
+
child.on("close", (code) => {
|
|
22488
|
+
const output = [stdout, stderr].filter(Boolean).join("\n").trim();
|
|
22489
|
+
resolve({
|
|
22490
|
+
success: code === 0,
|
|
22491
|
+
output
|
|
22492
|
+
});
|
|
22493
|
+
});
|
|
22494
|
+
});
|
|
22495
|
+
}
|
|
22496
|
+
async function runLocalTypecheck(projectRoot) {
|
|
22497
|
+
const dependencySkipReason = await ensureTypecheckDependencies(projectRoot);
|
|
22498
|
+
if (dependencySkipReason) {
|
|
22499
|
+
return {
|
|
22500
|
+
success: true,
|
|
22501
|
+
skipped: true,
|
|
22502
|
+
output: dependencySkipReason
|
|
22503
|
+
};
|
|
22504
|
+
}
|
|
22505
|
+
const runner = await resolveTypecheckRunner();
|
|
22506
|
+
if (!runner) {
|
|
22507
|
+
return {
|
|
22508
|
+
success: true,
|
|
22509
|
+
skipped: true,
|
|
22510
|
+
output: "Skipping local typecheck: TypeScript CLI was not found in workspace dependencies or on PATH."
|
|
22511
|
+
};
|
|
22512
|
+
}
|
|
22513
|
+
for (const projectPath of ["app/tsconfig.json", "ui/tsconfig.json"]) {
|
|
22514
|
+
const result = await runTypecheckProject(runner, projectRoot, projectPath);
|
|
22515
|
+
if (!result.success) {
|
|
22516
|
+
return result;
|
|
22517
|
+
}
|
|
22518
|
+
}
|
|
22519
|
+
return {
|
|
22520
|
+
success: true,
|
|
22521
|
+
output: ""
|
|
22522
|
+
};
|
|
22523
|
+
}
|
|
22524
|
+
|
|
22316
22525
|
// src/commands/push.ts
|
|
22317
22526
|
function isSourcePath(filePath) {
|
|
22318
22527
|
return filePath !== MANIFEST_FILE && filePath !== RULE_FILE && isAllowedGamePath2(filePath);
|
|
@@ -22320,33 +22529,48 @@ function isSourcePath(filePath) {
|
|
|
22320
22529
|
function buildSourceChanges(options) {
|
|
22321
22530
|
const { mode, localFiles, diff } = options;
|
|
22322
22531
|
if (mode === "replace") {
|
|
22323
|
-
return Object.entries(localFiles).filter(([filePath]) => isSourcePath(filePath)).sort(([left], [right]) => left.localeCompare(right)).map(([
|
|
22532
|
+
return Object.entries(localFiles).filter(([filePath]) => isSourcePath(filePath)).sort(([left], [right]) => left.localeCompare(right)).map(([path15, content]) => ({
|
|
22324
22533
|
kind: "upsert",
|
|
22325
|
-
path:
|
|
22534
|
+
path: path15,
|
|
22326
22535
|
content
|
|
22327
22536
|
}));
|
|
22328
22537
|
}
|
|
22329
22538
|
const changes = [];
|
|
22330
22539
|
const upsertPaths = [...diff.modified, ...diff.added].filter(isSourcePath).sort((left, right) => left.localeCompare(right));
|
|
22331
|
-
for (const
|
|
22332
|
-
const content = localFiles[
|
|
22540
|
+
for (const path15 of upsertPaths) {
|
|
22541
|
+
const content = localFiles[path15];
|
|
22333
22542
|
if (content === void 0) {
|
|
22334
22543
|
continue;
|
|
22335
22544
|
}
|
|
22336
22545
|
changes.push({
|
|
22337
22546
|
kind: "upsert",
|
|
22338
|
-
path:
|
|
22547
|
+
path: path15,
|
|
22339
22548
|
content
|
|
22340
22549
|
});
|
|
22341
22550
|
}
|
|
22342
|
-
for (const
|
|
22551
|
+
for (const path15 of diff.deleted.filter(isSourcePath).sort()) {
|
|
22343
22552
|
changes.push({
|
|
22344
22553
|
kind: "delete",
|
|
22345
|
-
path:
|
|
22554
|
+
path: path15
|
|
22346
22555
|
});
|
|
22347
22556
|
}
|
|
22348
22557
|
return changes;
|
|
22349
22558
|
}
|
|
22559
|
+
function formatCompileJobProgressMessage(job) {
|
|
22560
|
+
const phase = job.phase ? ` [${job.phase}]` : "";
|
|
22561
|
+
const detail = job.message ? ` ${job.message}` : "";
|
|
22562
|
+
if (job.status === "PENDING") {
|
|
22563
|
+
const queue = typeof job.queuePosition === "number" ? ` (queue ${job.queuePosition + 1})` : "";
|
|
22564
|
+
return `Compile queued${queue}${phase}${detail}`.trim();
|
|
22565
|
+
}
|
|
22566
|
+
if (job.status === "RUNNING") {
|
|
22567
|
+
return `Compile running${phase}${detail}`.trim();
|
|
22568
|
+
}
|
|
22569
|
+
if (job.status === "FAILED") {
|
|
22570
|
+
return `Compile failed${phase}${detail}`.trim();
|
|
22571
|
+
}
|
|
22572
|
+
return `Compile ${job.status.toLowerCase()}${phase}${detail}`.trim();
|
|
22573
|
+
}
|
|
22350
22574
|
var push_default = defineCommand({
|
|
22351
22575
|
meta: {
|
|
22352
22576
|
name: "push",
|
|
@@ -22363,6 +22587,11 @@ var push_default = defineCommand({
|
|
|
22363
22587
|
description: "Print debug details including source revision payloads",
|
|
22364
22588
|
default: false
|
|
22365
22589
|
},
|
|
22590
|
+
"skip-local-check": {
|
|
22591
|
+
type: "boolean",
|
|
22592
|
+
description: "Skip the best-effort local typecheck before remote mutations",
|
|
22593
|
+
default: false
|
|
22594
|
+
},
|
|
22366
22595
|
...CONFIG_FLAG_ARGS
|
|
22367
22596
|
},
|
|
22368
22597
|
async run({ args }) {
|
|
@@ -22406,6 +22635,24 @@ var push_default = defineCommand({
|
|
|
22406
22635
|
`Remote drift detected. Local base=${knownBaseResultId}, remote latest=${latest.id}. Run 'dreamboard update --pull' to reconcile before pushing.`
|
|
22407
22636
|
);
|
|
22408
22637
|
}
|
|
22638
|
+
if (!parsedArgs["skip-local-check"]) {
|
|
22639
|
+
consola.start("Running local typecheck...");
|
|
22640
|
+
const typecheckResult = await runLocalTypecheck(projectRoot);
|
|
22641
|
+
if (typecheckResult.skipped) {
|
|
22642
|
+
if (typecheckResult.output) {
|
|
22643
|
+
consola.warn(typecheckResult.output);
|
|
22644
|
+
}
|
|
22645
|
+
} else if (!typecheckResult.success) {
|
|
22646
|
+
if (typecheckResult.output) {
|
|
22647
|
+
consola.error(typecheckResult.output);
|
|
22648
|
+
}
|
|
22649
|
+
throw new Error(
|
|
22650
|
+
"Local typecheck failed. Fix the diagnostics or re-run with --skip-local-check."
|
|
22651
|
+
);
|
|
22652
|
+
} else {
|
|
22653
|
+
consola.success("Local typecheck passed.");
|
|
22654
|
+
}
|
|
22655
|
+
}
|
|
22409
22656
|
const ruleChanged = diff.modified.includes(RULE_FILE) || diff.added.includes(RULE_FILE);
|
|
22410
22657
|
const manifestChanged = diff.modified.includes(MANIFEST_FILE) || diff.added.includes(MANIFEST_FILE);
|
|
22411
22658
|
let manifestId = currentProjectConfig.manifestId;
|
|
@@ -22494,12 +22741,22 @@ ${sourceChanges.map((change) => ` - ${change.kind} ${change.path}`).join("\n")}
|
|
|
22494
22741
|
if (shouldCheckpointPrecompileState) {
|
|
22495
22742
|
await persistProjectProgress();
|
|
22496
22743
|
}
|
|
22497
|
-
const
|
|
22744
|
+
const compileJob = await createCompiledResultSdk({
|
|
22498
22745
|
gameId: currentProjectConfig.gameId,
|
|
22499
22746
|
sourceRevisionId,
|
|
22500
22747
|
manifestId,
|
|
22501
22748
|
ruleId
|
|
22502
22749
|
});
|
|
22750
|
+
if (debug) {
|
|
22751
|
+
consola.info(`[push --debug] compile job=${compileJob.jobId}`);
|
|
22752
|
+
}
|
|
22753
|
+
const { compiledResult } = await waitForCompiledResultJobSdk({
|
|
22754
|
+
gameId: currentProjectConfig.gameId,
|
|
22755
|
+
jobId: compileJob.jobId,
|
|
22756
|
+
onProgress: (job) => {
|
|
22757
|
+
consola.info(formatCompileJobProgressMessage(job));
|
|
22758
|
+
}
|
|
22759
|
+
});
|
|
22503
22760
|
await persistProjectProgress({
|
|
22504
22761
|
resultId: compiledResult.id,
|
|
22505
22762
|
sourceRevisionId: compiledResult.sourceRevisionId
|
|
@@ -22637,7 +22894,7 @@ var status_default = defineCommand({
|
|
|
22637
22894
|
});
|
|
22638
22895
|
|
|
22639
22896
|
// src/commands/update.ts
|
|
22640
|
-
import
|
|
22897
|
+
import path9 from "path";
|
|
22641
22898
|
|
|
22642
22899
|
// src/utils/prompts.ts
|
|
22643
22900
|
import { createInterface } from "readline/promises";
|
|
@@ -22805,14 +23062,14 @@ function findStalePhaseFiles(localFiles, expectedPhasePaths) {
|
|
|
22805
23062
|
async function mergeUiArgsFileIfNeeded(projectRoot, files) {
|
|
22806
23063
|
const incomingUiArgs = files[UI_ARGS_PATH];
|
|
22807
23064
|
if (incomingUiArgs === null || incomingUiArgs === void 0) return;
|
|
22808
|
-
const localPath =
|
|
23065
|
+
const localPath = path9.join(projectRoot, UI_ARGS_PATH);
|
|
22809
23066
|
const localUiArgs = await readTextFileIfExists(localPath);
|
|
22810
23067
|
if (localUiArgs === null) return;
|
|
22811
23068
|
if (localUiArgs.trim().length === 0) return;
|
|
22812
23069
|
if (localUiArgs === incomingUiArgs) return;
|
|
22813
23070
|
const mergeResult = mergeUiArgsContent(localUiArgs, incomingUiArgs);
|
|
22814
23071
|
files[UI_ARGS_PATH] = mergeResult.content;
|
|
22815
|
-
await ensureDir(
|
|
23072
|
+
await ensureDir(path9.dirname(localPath));
|
|
22816
23073
|
await writeTextFile(localPath, mergeResult.content);
|
|
22817
23074
|
if (mergeResult.conflicted) {
|
|
22818
23075
|
throw new Error(
|
|
@@ -23104,7 +23361,7 @@ var update_default = defineCommand({
|
|
|
23104
23361
|
});
|
|
23105
23362
|
|
|
23106
23363
|
// src/commands/run.ts
|
|
23107
|
-
import
|
|
23364
|
+
import path11 from "path";
|
|
23108
23365
|
import { appendFile } from "fs/promises";
|
|
23109
23366
|
|
|
23110
23367
|
// src/services/workflows/resolve-run-result.ts
|
|
@@ -23132,7 +23389,7 @@ async function resolveCompiledResultForRun(projectRoot, projectConfig) {
|
|
|
23132
23389
|
}
|
|
23133
23390
|
|
|
23134
23391
|
// src/ui/playwright-runner.ts
|
|
23135
|
-
import
|
|
23392
|
+
import path10 from "path";
|
|
23136
23393
|
async function runUiSteps(page, steps, outputDir, turnTracker) {
|
|
23137
23394
|
let stepIndex = 0;
|
|
23138
23395
|
for (const step of steps) {
|
|
@@ -23168,7 +23425,7 @@ async function runUiSteps(page, steps, outputDir, turnTracker) {
|
|
|
23168
23425
|
const turns = typeof step.turns === "number" ? step.turns : 1;
|
|
23169
23426
|
await turnTracker.waitForTurns(Math.max(0, Math.floor(turns)));
|
|
23170
23427
|
await page.screenshot({
|
|
23171
|
-
path:
|
|
23428
|
+
path: path10.join(outputDir, `step-${stepIndex}.png`)
|
|
23172
23429
|
});
|
|
23173
23430
|
stepIndex++;
|
|
23174
23431
|
}
|
|
@@ -23398,12 +23655,12 @@ var run_default = defineCommand({
|
|
|
23398
23655
|
webBaseUrl: config2.webBaseUrl,
|
|
23399
23656
|
parsedArgs
|
|
23400
23657
|
});
|
|
23401
|
-
const runDir =
|
|
23658
|
+
const runDir = path11.join(projectRoot, PROJECT_DIR_NAME, "run");
|
|
23402
23659
|
await ensureDir(runDir);
|
|
23403
|
-
const sessionFilePath =
|
|
23404
|
-
const eventsFilePath =
|
|
23405
|
-
const yourTurnFilePath =
|
|
23406
|
-
const summaryFilePath =
|
|
23660
|
+
const sessionFilePath = path11.join(runDir, "session.json");
|
|
23661
|
+
const eventsFilePath = path11.join(runDir, "events.ndjson");
|
|
23662
|
+
const yourTurnFilePath = path11.join(runDir, "latest-your-turn.json");
|
|
23663
|
+
const summaryFilePath = path11.join(runDir, "last-run-summary.json");
|
|
23407
23664
|
const shouldResume = !runtime.isEmbeddedHarness && parsedArgs.resume && !parsedArgs["new-session"];
|
|
23408
23665
|
const until = parsedArgs.until;
|
|
23409
23666
|
const observeEvents = parsedArgs["observe-events"];
|
|
@@ -23510,7 +23767,7 @@ var run_default = defineCommand({
|
|
|
23510
23767
|
"UI scenario execution requires Playwright page context, but browser was not initialized."
|
|
23511
23768
|
);
|
|
23512
23769
|
}
|
|
23513
|
-
const outputDir =
|
|
23770
|
+
const outputDir = path11.join(
|
|
23514
23771
|
projectRoot,
|
|
23515
23772
|
PROJECT_DIR_NAME,
|
|
23516
23773
|
"screenshots"
|
|
@@ -23593,13 +23850,13 @@ var run_default = defineCommand({
|
|
|
23593
23850
|
"Screenshot capture requires Playwright page context, but browser was not initialized."
|
|
23594
23851
|
);
|
|
23595
23852
|
}
|
|
23596
|
-
const outputDir =
|
|
23853
|
+
const outputDir = path11.join(
|
|
23597
23854
|
projectRoot,
|
|
23598
23855
|
PROJECT_DIR_NAME,
|
|
23599
23856
|
"screenshots"
|
|
23600
23857
|
);
|
|
23601
23858
|
await ensureDir(outputDir);
|
|
23602
|
-
const screenshotPath = parsedArgs.output ??
|
|
23859
|
+
const screenshotPath = parsedArgs.output ?? path11.join(outputDir, `run-${Date.now()}.png`);
|
|
23603
23860
|
if (screenshotDelayMs && screenshotDelayMs > 0) {
|
|
23604
23861
|
await sleep(screenshotDelayMs);
|
|
23605
23862
|
}
|
|
@@ -24501,13 +24758,13 @@ function extractGameStatePhase(event) {
|
|
|
24501
24758
|
}
|
|
24502
24759
|
|
|
24503
24760
|
// src/commands/start.ts
|
|
24504
|
-
import
|
|
24761
|
+
import path12 from "path";
|
|
24505
24762
|
|
|
24506
24763
|
// src/auth/auth-server.ts
|
|
24507
24764
|
import {
|
|
24508
24765
|
createServer
|
|
24509
24766
|
} from "http";
|
|
24510
|
-
import { spawn } from "child_process";
|
|
24767
|
+
import { spawn as spawn2 } from "child_process";
|
|
24511
24768
|
async function startCliAuthServer(state, timeoutMs) {
|
|
24512
24769
|
let resolveToken;
|
|
24513
24770
|
let rejectToken;
|
|
@@ -24622,7 +24879,7 @@ function openBrowser(url2) {
|
|
|
24622
24879
|
} else {
|
|
24623
24880
|
command = ["xdg-open", url2];
|
|
24624
24881
|
}
|
|
24625
|
-
const child =
|
|
24882
|
+
const child = spawn2(command[0], command.slice(1), {
|
|
24626
24883
|
stdio: "ignore",
|
|
24627
24884
|
detached: true
|
|
24628
24885
|
});
|
|
@@ -24691,8 +24948,8 @@ var start_default = defineCommand({
|
|
|
24691
24948
|
formatApiError(startError, startResponse, "Failed to start game")
|
|
24692
24949
|
);
|
|
24693
24950
|
}
|
|
24694
|
-
const runDir =
|
|
24695
|
-
const sessionFilePath =
|
|
24951
|
+
const runDir = path12.join(projectRoot, PROJECT_DIR_NAME, "run");
|
|
24952
|
+
const sessionFilePath = path12.join(runDir, "session.json");
|
|
24696
24953
|
await ensureDir(runDir);
|
|
24697
24954
|
const persistedSession = createPersistedRunSession({
|
|
24698
24955
|
sessionId: session.sessionId,
|
|
@@ -25061,7 +25318,7 @@ var config_default = defineCommand({
|
|
|
25061
25318
|
});
|
|
25062
25319
|
|
|
25063
25320
|
// src/commands/test.ts
|
|
25064
|
-
import
|
|
25321
|
+
import path14 from "path";
|
|
25065
25322
|
import { readdir as readdir2, unlink as unlink3 } from "fs/promises";
|
|
25066
25323
|
import { isDeepStrictEqual } from "util";
|
|
25067
25324
|
|
|
@@ -25076,7 +25333,7 @@ function shouldUseRemoteTestRuntime(environment) {
|
|
|
25076
25333
|
// src/utils/ts-module-loader.ts
|
|
25077
25334
|
import { mkdtemp, rm } from "fs/promises";
|
|
25078
25335
|
import { tmpdir } from "os";
|
|
25079
|
-
import
|
|
25336
|
+
import path13 from "path";
|
|
25080
25337
|
import { pathToFileURL } from "url";
|
|
25081
25338
|
import { build } from "esbuild";
|
|
25082
25339
|
var ESBUILD_EXTERNALS = [
|
|
@@ -25086,10 +25343,10 @@ var ESBUILD_EXTERNALS = [
|
|
|
25086
25343
|
"electron"
|
|
25087
25344
|
];
|
|
25088
25345
|
async function importTypeScriptModule(entryPath) {
|
|
25089
|
-
const tempDir = await mkdtemp(
|
|
25090
|
-
const outfile =
|
|
25346
|
+
const tempDir = await mkdtemp(path13.join(tmpdir(), "dreamboard-ts-module-"));
|
|
25347
|
+
const outfile = path13.join(
|
|
25091
25348
|
tempDir,
|
|
25092
|
-
`${
|
|
25349
|
+
`${path13.basename(entryPath).replace(/\.[^.]+$/u, "")}.mjs`
|
|
25093
25350
|
);
|
|
25094
25351
|
try {
|
|
25095
25352
|
await build({
|
|
@@ -25215,7 +25472,7 @@ var generateCommand = defineCommand({
|
|
|
25215
25472
|
}
|
|
25216
25473
|
};
|
|
25217
25474
|
}
|
|
25218
|
-
const generatedDir =
|
|
25475
|
+
const generatedDir = path14.join(projectRoot, "test", "generated");
|
|
25219
25476
|
await ensureDir(generatedDir);
|
|
25220
25477
|
await writeGeneratedFiles({
|
|
25221
25478
|
generatedDir,
|
|
@@ -25415,7 +25672,7 @@ async function runSingleScenario(options) {
|
|
|
25415
25672
|
});
|
|
25416
25673
|
}
|
|
25417
25674
|
async function loadGeneratedBaseStates(projectRoot) {
|
|
25418
|
-
const filePath =
|
|
25675
|
+
const filePath = path14.join(
|
|
25419
25676
|
projectRoot,
|
|
25420
25677
|
"test",
|
|
25421
25678
|
"generated",
|
|
@@ -25434,7 +25691,7 @@ async function loadGeneratedBaseStates(projectRoot) {
|
|
|
25434
25691
|
return baseStates;
|
|
25435
25692
|
}
|
|
25436
25693
|
async function loadScenarios(projectRoot, options) {
|
|
25437
|
-
const scenarioFiles = options.scenarioPath ? [
|
|
25694
|
+
const scenarioFiles = options.scenarioPath ? [path14.resolve(projectRoot, options.scenarioPath)] : await discoverScenarioFiles(path14.join(projectRoot, "test", "scenarios"));
|
|
25438
25695
|
const loaded = [];
|
|
25439
25696
|
for (const scenarioFile of scenarioFiles) {
|
|
25440
25697
|
const module = await importTypeScriptModule(scenarioFile);
|
|
@@ -25463,7 +25720,7 @@ async function discoverScenarioFiles(root) {
|
|
|
25463
25720
|
const entries = await readdir2(root, { withFileTypes: true });
|
|
25464
25721
|
const files = [];
|
|
25465
25722
|
for (const entry of entries) {
|
|
25466
|
-
const entryPath =
|
|
25723
|
+
const entryPath = path14.join(root, entry.name);
|
|
25467
25724
|
if (entry.isDirectory()) {
|
|
25468
25725
|
files.push(...await discoverScenarioFiles(entryPath));
|
|
25469
25726
|
continue;
|
|
@@ -25549,8 +25806,8 @@ async function writeGeneratedFiles(options) {
|
|
|
25549
25806
|
`;
|
|
25550
25807
|
const manifest = options.scenarios.map((scenario) => ({
|
|
25551
25808
|
id: scenario.scenario.meta.id,
|
|
25552
|
-
filePath:
|
|
25553
|
-
|
|
25809
|
+
filePath: path14.relative(
|
|
25810
|
+
path14.dirname(options.generatedDir),
|
|
25554
25811
|
scenario.filePath
|
|
25555
25812
|
),
|
|
25556
25813
|
base: scenario.scenario.given.base
|
|
@@ -25558,19 +25815,19 @@ async function writeGeneratedFiles(options) {
|
|
|
25558
25815
|
const scenarioManifestContent = `${generatedHeader}export const SCENARIO_MANIFEST = ${JSON.stringify(manifest, null, 2)} as const;
|
|
25559
25816
|
`;
|
|
25560
25817
|
await writeTextFile(
|
|
25561
|
-
|
|
25818
|
+
path14.join(options.generatedDir, "base-states.generated.ts"),
|
|
25562
25819
|
baseStatesContent
|
|
25563
25820
|
);
|
|
25564
25821
|
await writeTextFile(
|
|
25565
|
-
|
|
25822
|
+
path14.join(options.generatedDir, "base-states.generated.d.ts"),
|
|
25566
25823
|
baseStatesDtsContent
|
|
25567
25824
|
);
|
|
25568
25825
|
await writeTextFile(
|
|
25569
|
-
|
|
25826
|
+
path14.join(options.generatedDir, "scenario-manifest.generated.ts"),
|
|
25570
25827
|
scenarioManifestContent
|
|
25571
25828
|
);
|
|
25572
25829
|
await writeJsonFile(
|
|
25573
|
-
|
|
25830
|
+
path14.join(options.generatedDir, ".generation-meta.json"),
|
|
25574
25831
|
{
|
|
25575
25832
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25576
25833
|
scenarioCount: options.scenarios.length,
|
|
@@ -25579,7 +25836,7 @@ async function writeGeneratedFiles(options) {
|
|
|
25579
25836
|
);
|
|
25580
25837
|
}
|
|
25581
25838
|
async function ensureScenarioImportShim(projectRoot) {
|
|
25582
|
-
const testingTypesRuntimePath =
|
|
25839
|
+
const testingTypesRuntimePath = path14.join(
|
|
25583
25840
|
projectRoot,
|
|
25584
25841
|
"test",
|
|
25585
25842
|
"testing-types.ts"
|
|
@@ -25588,11 +25845,11 @@ async function ensureScenarioImportShim(projectRoot) {
|
|
|
25588
25845
|
testingTypesRuntimePath
|
|
25589
25846
|
);
|
|
25590
25847
|
if (shouldRefreshGeneratedTestingTypes2(existingTestingTypes)) {
|
|
25591
|
-
await ensureDir(
|
|
25848
|
+
await ensureDir(path14.dirname(testingTypesRuntimePath));
|
|
25592
25849
|
await writeTextFile(testingTypesRuntimePath, TESTING_TYPES_CONTENT);
|
|
25593
25850
|
}
|
|
25594
25851
|
await migrateLegacyScenarioImports(projectRoot);
|
|
25595
|
-
const staleDtsPath =
|
|
25852
|
+
const staleDtsPath = path14.join(projectRoot, "test", "testing-types.d.ts");
|
|
25596
25853
|
if (await exists(staleDtsPath)) {
|
|
25597
25854
|
await unlink3(staleDtsPath);
|
|
25598
25855
|
}
|
|
@@ -25837,7 +26094,7 @@ function validateFingerprint(options) {
|
|
|
25837
26094
|
}
|
|
25838
26095
|
}
|
|
25839
26096
|
async function loadBaseScenarioDefinitions(projectRoot) {
|
|
25840
|
-
const filePath =
|
|
26097
|
+
const filePath = path14.join(projectRoot, "test", "base-scenarios.json");
|
|
25841
26098
|
if (!await exists(filePath)) {
|
|
25842
26099
|
throw new Error(
|
|
25843
26100
|
"Missing test/base-scenarios.json. Define base checkpoints there, including 'initial-turn'."
|
|
@@ -25871,7 +26128,7 @@ async function loadBaseScenarioDefinitions(projectRoot) {
|
|
|
25871
26128
|
function validateScenarioBases(scenarios, baseScenarios) {
|
|
25872
26129
|
const available = new Set(Object.keys(baseScenarios));
|
|
25873
26130
|
const invalid = scenarios.filter((scenario) => !available.has(scenario.scenario.given.base)).map(
|
|
25874
|
-
(scenario) =>
|
|
26131
|
+
(scenario) => path14.relative(process.cwd(), scenario.filePath) + ` -> '${scenario.scenario.given.base}'`
|
|
25875
26132
|
);
|
|
25876
26133
|
if (invalid.length === 0) {
|
|
25877
26134
|
return;
|
|
@@ -25956,7 +26213,7 @@ var subCommands = {
|
|
|
25956
26213
|
var main = defineCommand({
|
|
25957
26214
|
meta: {
|
|
25958
26215
|
name: "dreamboard",
|
|
25959
|
-
version: "0.1.
|
|
26216
|
+
version: "0.1.6",
|
|
25960
26217
|
description: "Dreamboard CLI \u2014 game development platform"
|
|
25961
26218
|
},
|
|
25962
26219
|
subCommands
|