@dreamboard-games/cli 0.1.30-alpha.2 → 0.1.30-alpha.3

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 (87) hide show
  1. package/dist/agent-verifier/agent-workspace-verifier.mjs +227 -0
  2. package/dist/agent-verifier/agent-workspace-verifier.mjs.map +1 -0
  3. package/dist/agent-verifier/chunk-3UKQVWLV.mjs +1744 -0
  4. package/dist/agent-verifier/chunk-3UKQVWLV.mjs.map +1 -0
  5. package/dist/agent-verifier/chunk-776W3UGV.mjs +167 -0
  6. package/dist/agent-verifier/chunk-776W3UGV.mjs.map +1 -0
  7. package/dist/agent-verifier/chunk-7WWGFAAU.mjs +729 -0
  8. package/dist/agent-verifier/chunk-7WWGFAAU.mjs.map +1 -0
  9. package/dist/agent-verifier/chunk-A64ZZUZV.mjs +261 -0
  10. package/dist/agent-verifier/chunk-A64ZZUZV.mjs.map +1 -0
  11. package/dist/agent-verifier/chunk-E7SSWJXJ.mjs +3137 -0
  12. package/dist/agent-verifier/chunk-E7SSWJXJ.mjs.map +1 -0
  13. package/dist/agent-verifier/chunk-F2DIOJJZ.mjs +302 -0
  14. package/dist/agent-verifier/chunk-F2DIOJJZ.mjs.map +1 -0
  15. package/dist/agent-verifier/chunk-G42BGGG2.mjs +70 -0
  16. package/dist/agent-verifier/chunk-G42BGGG2.mjs.map +1 -0
  17. package/dist/agent-verifier/chunk-H76MT5UR.mjs +57 -0
  18. package/dist/agent-verifier/chunk-H76MT5UR.mjs.map +1 -0
  19. package/dist/agent-verifier/chunk-HGMUAL33.mjs +39 -0
  20. package/dist/agent-verifier/chunk-HGMUAL33.mjs.map +1 -0
  21. package/dist/agent-verifier/chunk-IAYRNVUC.mjs +49 -0
  22. package/dist/agent-verifier/chunk-IAYRNVUC.mjs.map +1 -0
  23. package/dist/agent-verifier/chunk-JGT4P4UD.mjs +45 -0
  24. package/dist/agent-verifier/chunk-JGT4P4UD.mjs.map +1 -0
  25. package/dist/agent-verifier/chunk-LUZ7KE6H.mjs +79 -0
  26. package/dist/agent-verifier/chunk-LUZ7KE6H.mjs.map +1 -0
  27. package/dist/agent-verifier/chunk-NAK77WXW.mjs +767 -0
  28. package/dist/agent-verifier/chunk-NAK77WXW.mjs.map +1 -0
  29. package/dist/agent-verifier/chunk-O4YCPU7C.mjs +2913 -0
  30. package/dist/agent-verifier/chunk-O4YCPU7C.mjs.map +1 -0
  31. package/dist/agent-verifier/chunk-S34FRJHS.mjs +222 -0
  32. package/dist/agent-verifier/chunk-S34FRJHS.mjs.map +1 -0
  33. package/dist/agent-verifier/chunk-SH5JKYOB.mjs +226 -0
  34. package/dist/agent-verifier/chunk-SH5JKYOB.mjs.map +1 -0
  35. package/dist/agent-verifier/chunk-SKI2ESE5.mjs +44 -0
  36. package/dist/agent-verifier/chunk-SKI2ESE5.mjs.map +1 -0
  37. package/dist/agent-verifier/chunk-TAEQKBJB.mjs +107 -0
  38. package/dist/agent-verifier/chunk-TAEQKBJB.mjs.map +1 -0
  39. package/dist/agent-verifier/chunk-UIOLGH4A.mjs +150 -0
  40. package/dist/agent-verifier/chunk-UIOLGH4A.mjs.map +1 -0
  41. package/dist/agent-verifier/chunk-UIZNWRM6.mjs +2432 -0
  42. package/dist/agent-verifier/chunk-UIZNWRM6.mjs.map +1 -0
  43. package/dist/agent-verifier/chunk-VS573ERH.mjs +14523 -0
  44. package/dist/agent-verifier/chunk-VS573ERH.mjs.map +1 -0
  45. package/dist/agent-verifier/chunk-W3N3QJ4V.mjs +624 -0
  46. package/dist/agent-verifier/chunk-W3N3QJ4V.mjs.map +1 -0
  47. package/dist/agent-verifier/chunk-XGWCY624.mjs +185 -0
  48. package/dist/agent-verifier/chunk-XGWCY624.mjs.map +1 -0
  49. package/dist/agent-verifier/chunk-XQXDOBYB.mjs +382 -0
  50. package/dist/agent-verifier/chunk-XQXDOBYB.mjs.map +1 -0
  51. package/dist/agent-verifier/chunk-YE7UAO3T.mjs +129 -0
  52. package/dist/agent-verifier/chunk-YE7UAO3T.mjs.map +1 -0
  53. package/dist/agent-verifier/chunk-ZEELHSY3.mjs +20 -0
  54. package/dist/agent-verifier/chunk-ZEELHSY3.mjs.map +1 -0
  55. package/dist/agent-verifier/compile-TEQVA46V.mjs +312 -0
  56. package/dist/agent-verifier/compile-TEQVA46V.mjs.map +1 -0
  57. package/dist/agent-verifier/global-config-Y2NTSK4R.mjs +18 -0
  58. package/dist/agent-verifier/global-config-Y2NTSK4R.mjs.map +1 -0
  59. package/dist/agent-verifier/keychain-backend-SPQWGKZN.mjs +135 -0
  60. package/dist/agent-verifier/keychain-backend-SPQWGKZN.mjs.map +1 -0
  61. package/dist/agent-verifier/local-files-JFOQQZDL.mjs +45 -0
  62. package/dist/agent-verifier/local-files-JFOQQZDL.mjs.map +1 -0
  63. package/dist/agent-verifier/local-typecheck-XVGWI75X.mjs +10 -0
  64. package/dist/agent-verifier/local-typecheck-XVGWI75X.mjs.map +1 -0
  65. package/dist/agent-verifier/materialize-workspace-ZAVGQQSF.mjs +89 -0
  66. package/dist/agent-verifier/materialize-workspace-ZAVGQQSF.mjs.map +1 -0
  67. package/dist/agent-verifier/project-state-K576C2TE.mjs +33 -0
  68. package/dist/agent-verifier/project-state-K576C2TE.mjs.map +1 -0
  69. package/dist/agent-verifier/prompt-MJRJMOGQ.mjs +756 -0
  70. package/dist/agent-verifier/prompt-MJRJMOGQ.mjs.map +1 -0
  71. package/dist/agent-verifier/reducer-bundle-preflight-LXNJUBKL.mjs +20 -0
  72. package/dist/agent-verifier/reducer-bundle-preflight-LXNJUBKL.mjs.map +1 -0
  73. package/dist/agent-verifier/reducer-contract-preflight-TUMQ43JV.mjs +11 -0
  74. package/dist/agent-verifier/reducer-contract-preflight-TUMQ43JV.mjs.map +1 -0
  75. package/dist/agent-verifier/reducer-native-test-harness-CHX5MBL5.mjs +50 -0
  76. package/dist/agent-verifier/reducer-native-test-harness-CHX5MBL5.mjs.map +1 -0
  77. package/dist/agent-verifier/static-scaffold-R7SVDRQI.mjs +27 -0
  78. package/dist/agent-verifier/static-scaffold-R7SVDRQI.mjs.map +1 -0
  79. package/dist/agent-verifier/sync-THAI546U.mjs +588 -0
  80. package/dist/agent-verifier/sync-THAI546U.mjs.map +1 -0
  81. package/dist/agent-verifier/test-AFAQFKOB.mjs +353 -0
  82. package/dist/agent-verifier/test-AFAQFKOB.mjs.map +1 -0
  83. package/dist/agent-verifier/workspace-codegen-2ZMQRIKJ.mjs +10 -0
  84. package/dist/agent-verifier/workspace-codegen-2ZMQRIKJ.mjs.map +1 -0
  85. package/dist/agent-verifier/workspace-dependencies-NOOQBK6I.mjs +15 -0
  86. package/dist/agent-verifier/workspace-dependencies-NOOQBK6I.mjs.map +1 -0
  87. package/package.json +3 -2
@@ -0,0 +1,624 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ toDreamboardApiError
4
+ } from "./chunk-S34FRJHS.mjs";
5
+ import {
6
+ createGameRevision,
7
+ createProjectSourceBlobUploadSession,
8
+ ensureProject,
9
+ getApiVersion,
10
+ getCompiledResult,
11
+ getCurrentAuthUser,
12
+ getJob,
13
+ getProjectCompiledResult,
14
+ listCompiledResults,
15
+ listProjectCompiledResults,
16
+ queueProjectRevisionCompile,
17
+ uploadInitialProjection
18
+ } from "./chunk-O4YCPU7C.mjs";
19
+ import {
20
+ external_exports
21
+ } from "./chunk-VS573ERH.mjs";
22
+
23
+ // ../../node_modules/.pnpm/citty@0.2.2/node_modules/citty/dist/index.mjs
24
+ import { parseArgs as parseArgs$1 } from "util";
25
+ function defineCommand(def) {
26
+ return def;
27
+ }
28
+
29
+ // ../../packages/api-client/dist/source-revisions.js
30
+ var textEncoder = new TextEncoder();
31
+ function bytesToHex(bytes) {
32
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
33
+ }
34
+ async function sha256Hex(bytes) {
35
+ const normalizedBytes = new Uint8Array(bytes.byteLength);
36
+ normalizedBytes.set(bytes);
37
+ const digest = await crypto.subtle.digest("SHA-256", normalizedBytes.buffer);
38
+ return bytesToHex(new Uint8Array(digest));
39
+ }
40
+ function getUtf8ByteSize(content) {
41
+ return textEncoder.encode(content).byteLength;
42
+ }
43
+ async function computeSourceContentHash(content) {
44
+ return sha256Hex(textEncoder.encode(content));
45
+ }
46
+ async function describeSourceBlob(content) {
47
+ return {
48
+ contentHash: await computeSourceContentHash(content),
49
+ byteSize: getUtf8ByteSize(content)
50
+ };
51
+ }
52
+ async function materializeSourceChangeOperations(changes) {
53
+ const blobsByHash = /* @__PURE__ */ new Map();
54
+ const materialized = await Promise.all(Array.from(changes, async (change) => {
55
+ if (change.kind === "delete") {
56
+ return change;
57
+ }
58
+ const blob = await describeSourceBlob(change.content);
59
+ const existing = blobsByHash.get(blob.contentHash);
60
+ if (!existing) {
61
+ blobsByHash.set(blob.contentHash, blob);
62
+ }
63
+ return {
64
+ kind: "upsert",
65
+ path: change.path,
66
+ contentHash: blob.contentHash,
67
+ byteSize: blob.byteSize
68
+ };
69
+ }));
70
+ return {
71
+ blobs: Array.from(blobsByHash.values()).sort((left, right) => left.contentHash.localeCompare(right.contentHash)),
72
+ changes: materialized
73
+ };
74
+ }
75
+ function mapUpsertBlobContentsByContentHash(localChanges, materializedChanges) {
76
+ const uploadBlobs = /* @__PURE__ */ new Map();
77
+ const length = Math.min(localChanges.length, materializedChanges.length);
78
+ for (let index = 0; index < length; index += 1) {
79
+ const localChange = localChanges[index];
80
+ const materializedChange = materializedChanges[index];
81
+ if (localChange?.kind !== "upsert" || materializedChange?.kind !== "upsert") {
82
+ continue;
83
+ }
84
+ uploadBlobs.set(materializedChange.contentHash, {
85
+ contentHash: materializedChange.contentHash,
86
+ byteSize: materializedChange.byteSize,
87
+ content: localChange.content
88
+ });
89
+ }
90
+ return uploadBlobs;
91
+ }
92
+ var SourceBlobUploadError = class extends Error {
93
+ constructor(status, details) {
94
+ const suffix = details.trim().length > 0 ? `: ${details.trim()}` : "";
95
+ super(`Failed to upload source blob (HTTP ${status}${suffix})`);
96
+ this.name = "SourceBlobUploadError";
97
+ this.status = status;
98
+ this.details = details;
99
+ }
100
+ };
101
+ function isDuplicateDirectUploadError(error) {
102
+ if (!(error instanceof SourceBlobUploadError)) {
103
+ return false;
104
+ }
105
+ if (error.status === 409) {
106
+ return true;
107
+ }
108
+ const normalizedDetails = error.details.toLowerCase();
109
+ return normalizedDetails.includes("duplicate") || normalizedDetails.includes("already exists") || normalizedDetails.includes("resource already exists");
110
+ }
111
+ async function uploadSourceBlob(uploadTarget, content) {
112
+ const response = await fetch(uploadTarget.url, {
113
+ method: uploadTarget.method,
114
+ headers: uploadTarget.headers,
115
+ body: textEncoder.encode(content)
116
+ });
117
+ if (response.ok) {
118
+ return;
119
+ }
120
+ const details = await response.text().catch(() => "");
121
+ throw new SourceBlobUploadError(response.status, details);
122
+ }
123
+ var SourceBlobSessionRequestError = class extends Error {
124
+ constructor(message, apiError, response) {
125
+ super(message);
126
+ this.name = "SourceBlobSessionRequestError";
127
+ this.apiError = apiError;
128
+ this.response = response;
129
+ }
130
+ };
131
+ function assertSourceBlobUploadSession(data, response) {
132
+ if (!data || typeof data !== "object" || !Array.isArray(data.uploads)) {
133
+ throw new SourceBlobSessionRequestError("Source blob upload session response did not include an uploads array", data, response);
134
+ }
135
+ }
136
+ async function confirmSourceBlobAlreadyExists(options) {
137
+ const { requestUploadSession, blob } = options;
138
+ const { data, error, response } = await requestUploadSession([
139
+ {
140
+ contentHash: blob.contentHash,
141
+ byteSize: blob.byteSize
142
+ }
143
+ ]);
144
+ if (error || !data) {
145
+ throw new SourceBlobSessionRequestError("Failed to create source blob upload session", error, response);
146
+ }
147
+ assertSourceBlobUploadSession(data, response);
148
+ return data.uploads[0]?.status === "exists";
149
+ }
150
+ async function uploadSourceBlobs(options) {
151
+ const { blobs, requestUploadSession } = options;
152
+ const uniqueBlobs = /* @__PURE__ */ new Map();
153
+ for (const blob of blobs) {
154
+ const existing = uniqueBlobs.get(blob.contentHash);
155
+ if (!existing) {
156
+ uniqueBlobs.set(blob.contentHash, blob);
157
+ continue;
158
+ }
159
+ if (existing.byteSize !== blob.byteSize) {
160
+ throw new Error(`Source blob ${blob.contentHash} has conflicting byte sizes.`);
161
+ }
162
+ }
163
+ if (uniqueBlobs.size === 0) {
164
+ return;
165
+ }
166
+ const { data, error, response } = await requestUploadSession(Array.from(uniqueBlobs.values(), ({ contentHash, byteSize }) => ({
167
+ contentHash,
168
+ byteSize
169
+ })));
170
+ if (error || !data) {
171
+ throw new SourceBlobSessionRequestError("Failed to create source blob upload session", error, response);
172
+ }
173
+ assertSourceBlobUploadSession(data, response);
174
+ for (const upload of data.uploads) {
175
+ if (upload.status !== "upload_required") {
176
+ continue;
177
+ }
178
+ const blob = uniqueBlobs.get(upload.contentHash);
179
+ if (!blob) {
180
+ throw new Error(`Upload session referenced unknown source blob ${upload.contentHash}.`);
181
+ }
182
+ if (!upload.uploadTarget) {
183
+ throw new Error(`Upload target missing for source blob ${upload.contentHash}.`);
184
+ }
185
+ try {
186
+ await uploadSourceBlob(upload.uploadTarget, blob.content);
187
+ if (!await confirmSourceBlobAlreadyExists({ requestUploadSession, blob })) {
188
+ throw new Error(`Source blob ${blob.contentHash} was uploaded but not registered.`);
189
+ }
190
+ } catch (error2) {
191
+ if (isDuplicateDirectUploadError(error2) && await confirmSourceBlobAlreadyExists({ requestUploadSession, blob })) {
192
+ continue;
193
+ }
194
+ throw error2;
195
+ }
196
+ }
197
+ }
198
+ async function uploadProjectSourceBlobs(options) {
199
+ const { projectId, blobs } = options;
200
+ return uploadSourceBlobs({
201
+ blobs,
202
+ requestUploadSession: (uploadBlobs) => createProjectSourceBlobUploadSession({
203
+ path: { projectId },
204
+ body: { blobs: uploadBlobs }
205
+ })
206
+ });
207
+ }
208
+
209
+ // src/command-args.ts
210
+ var CONFIG_FLAG_ARGS = {
211
+ env: {
212
+ type: "string",
213
+ description: "Environment: local | staging | prod"
214
+ },
215
+ token: {
216
+ type: "string",
217
+ description: "Auth token (Dreamboard bearer JWT)"
218
+ }
219
+ };
220
+
221
+ // src/flags.ts
222
+ var configFlagsSchema = external_exports.object({
223
+ env: external_exports.enum(["local", "staging", "prod"]).optional(),
224
+ token: external_exports.string().optional()
225
+ });
226
+ var ruleInputFlagsSchema = external_exports.object({
227
+ "rule-file": external_exports.string().optional(),
228
+ rule: external_exports.string().optional()
229
+ });
230
+ var playerCountFlagsSchema = external_exports.object({
231
+ players: external_exports.string().optional(),
232
+ "player-count": external_exports.string().optional()
233
+ });
234
+ var newCommandArgsSchema = configFlagsSchema.extend({
235
+ slug: external_exports.string().min(1),
236
+ description: external_exports.string().min(1),
237
+ force: external_exports.boolean().default(false)
238
+ });
239
+ var cloneCommandArgsSchema = configFlagsSchema.extend({
240
+ slug: external_exports.string().min(1)
241
+ });
242
+ var queryCommandArgsSchema = configFlagsSchema.extend({
243
+ title: external_exports.string().min(1)
244
+ });
245
+ var pullCommandArgsSchema = configFlagsSchema.extend({
246
+ force: external_exports.boolean().default(false)
247
+ });
248
+ var syncCommandArgsSchema = configFlagsSchema.extend({
249
+ force: external_exports.boolean().default(false),
250
+ yes: external_exports.boolean().default(false)
251
+ });
252
+ var compileCommandArgsSchema = configFlagsSchema.extend({
253
+ debug: external_exports.boolean().default(false),
254
+ "skip-local-check": external_exports.boolean().default(false)
255
+ });
256
+ var statusCommandArgsSchema = configFlagsSchema.extend({
257
+ json: external_exports.boolean().default(false)
258
+ });
259
+ var devCommandArgsSchema = configFlagsSchema.extend({
260
+ seed: external_exports.string().optional(),
261
+ "setup-profile": external_exports.string().optional(),
262
+ players: external_exports.string().optional(),
263
+ "player-count": external_exports.string().optional(),
264
+ debug: external_exports.boolean().default(false),
265
+ resume: external_exports.string().optional(),
266
+ "from-scenario": external_exports.string().optional(),
267
+ "new-session": external_exports.boolean().default(false),
268
+ open: external_exports.boolean().default(false),
269
+ port: external_exports.string().optional(),
270
+ host: external_exports.union([external_exports.string(), external_exports.boolean()]).optional(),
271
+ "allowed-host": external_exports.string().optional()
272
+ });
273
+ var joinCommandArgsSchema = configFlagsSchema.extend({
274
+ session: external_exports.string().min(1).optional(),
275
+ player: external_exports.string().min(1),
276
+ "raw-events": external_exports.boolean().default(false)
277
+ });
278
+ var configCommandArgsSchema = configFlagsSchema.extend({
279
+ action: external_exports.string().optional().default("show"),
280
+ scope: external_exports.enum(["global", "workspace"]).optional().default("global")
281
+ });
282
+ var authCommandArgsSchema = external_exports.object({
283
+ action: external_exports.enum(["set", "clear", "login", "env", "status"]),
284
+ tokenValue: external_exports.string().optional(),
285
+ token: external_exports.string().optional(),
286
+ jwt: external_exports.boolean().optional(),
287
+ env: external_exports.enum(["local", "staging", "prod"]).optional()
288
+ });
289
+ function parseArgs(commandName, schema, args) {
290
+ const parsed = schema.safeParse(args);
291
+ if (parsed.success) {
292
+ return parsed.data;
293
+ }
294
+ const details = parsed.error.issues.map((issue) => {
295
+ const field = issue.path.length > 0 ? issue.path.join(".") : "args";
296
+ return `${field}: ${issue.message}`;
297
+ }).join("; ");
298
+ throw new Error(`Invalid arguments for '${commandName}': ${details}`);
299
+ }
300
+ function parseConfigFlags(args) {
301
+ return parseArgs("config-flags", configFlagsSchema, args);
302
+ }
303
+ function parseSyncCommandArgs(args) {
304
+ return parseArgs("sync", syncCommandArgsSchema, args);
305
+ }
306
+ function parseCompileCommandArgs(args) {
307
+ return parseArgs("compile", compileCommandArgsSchema, args);
308
+ }
309
+
310
+ // src/utils/strings.ts
311
+ import path from "path";
312
+ function titleFromSlug(slug) {
313
+ return slug.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
314
+ }
315
+ function sleep(ms) {
316
+ return new Promise((resolve) => setTimeout(resolve, ms));
317
+ }
318
+
319
+ // src/services/api/compiled-results-api.ts
320
+ var COMPILE_JOB_POLL_INTERVAL_MS = 1e3;
321
+ var DEFAULT_COMPILE_JOB_WAIT_TIMEOUT_MS = 10 * 60 * 1e3;
322
+ function firstNonEmpty(...values) {
323
+ for (const value of values) {
324
+ if (typeof value === "string" && value.trim().length > 0) {
325
+ return value.trim();
326
+ }
327
+ }
328
+ return null;
329
+ }
330
+ function formatTerminalCompileJobMessage(job) {
331
+ const detail = firstNonEmpty(job.errorMessage, job.message);
332
+ const phase = firstNonEmpty(job.phase);
333
+ const prefix = `Compile ${job.status.toLowerCase()}${phase ? ` [${phase}]` : ""}`;
334
+ return detail ? `${prefix}: ${detail}` : `${prefix}: job ${job.jobId} ended before a compiled result was created.`;
335
+ }
336
+ function compareCreatedAtDesc(left, right) {
337
+ const leftTime = Date.parse(left.createdAt);
338
+ const rightTime = Date.parse(right.createdAt);
339
+ if (Number.isFinite(leftTime) && Number.isFinite(rightTime)) {
340
+ return rightTime - leftTime;
341
+ }
342
+ if (Number.isFinite(rightTime)) {
343
+ return 1;
344
+ }
345
+ if (Number.isFinite(leftTime)) {
346
+ return -1;
347
+ }
348
+ return 0;
349
+ }
350
+ async function findFallbackCompiledResultForJob(options) {
351
+ const { gameId, projectId, job } = options;
352
+ const results = projectId ? await listProjectCompiledResults({
353
+ path: { projectId },
354
+ query: { limit: 100 }
355
+ }) : await listCompiledResults({
356
+ path: { gameId },
357
+ query: { limit: 100 }
358
+ });
359
+ if (results.error || !results.data) {
360
+ return null;
361
+ }
362
+ if (results.data.results.length === 0) {
363
+ return null;
364
+ }
365
+ const jobCreatedAtMs = Date.parse(job.createdAt);
366
+ const resultsCreatedAfterJob = Number.isFinite(jobCreatedAtMs) ? results.data.results.filter((result) => {
367
+ const resultCreatedAtMs = Date.parse(result.createdAt);
368
+ return !Number.isFinite(resultCreatedAtMs) || resultCreatedAtMs >= jobCreatedAtMs;
369
+ }) : results.data.results;
370
+ const candidateResults = resultsCreatedAfterJob.length > 0 ? resultsCreatedAfterJob : results.data.results;
371
+ return [...candidateResults].sort(compareCreatedAtDesc)[0] ?? null;
372
+ }
373
+ async function getCompiledResultSdk(gameId, compiledResultId) {
374
+ const { data, error, response } = await getCompiledResult({
375
+ path: {
376
+ gameId,
377
+ compiledResultId
378
+ }
379
+ });
380
+ if (error || !data) {
381
+ throw toDreamboardApiError(
382
+ error,
383
+ response,
384
+ "Failed to fetch compiled result"
385
+ );
386
+ }
387
+ return data;
388
+ }
389
+ async function findProjectCompiledResultsForRevision(options) {
390
+ const { projectId, revisionDigest } = options;
391
+ const { data, error, response } = await listProjectCompiledResults({
392
+ path: { projectId },
393
+ query: { limit: 100 }
394
+ });
395
+ if (error || !data) {
396
+ throw toDreamboardApiError(
397
+ error,
398
+ response,
399
+ "Failed to list compiled results"
400
+ );
401
+ }
402
+ return data.results.filter(
403
+ (result) => {
404
+ const maybeRevisionDigest = result.revisionDigest;
405
+ return maybeRevisionDigest === revisionDigest || result.authoringStateId === revisionDigest;
406
+ }
407
+ );
408
+ }
409
+ async function getProjectCompiledResultSdk(projectId, compiledResultId) {
410
+ const { data, error, response } = await getProjectCompiledResult({
411
+ path: { projectId, compiledResultId }
412
+ });
413
+ if (error || !data) {
414
+ throw toDreamboardApiError(
415
+ error,
416
+ response,
417
+ "Failed to fetch compiled result"
418
+ );
419
+ }
420
+ return data;
421
+ }
422
+ async function queueProjectRevisionCompileSdk(options) {
423
+ const { data, error, response } = await queueProjectRevisionCompile({
424
+ path: {
425
+ projectId: options.projectId,
426
+ revisionDigest: options.revisionDigest
427
+ }
428
+ });
429
+ if (error || !data) {
430
+ throw toDreamboardApiError(error, response, "Failed to create compile job");
431
+ }
432
+ return data;
433
+ }
434
+ async function waitForCompiledResultJobSdk(options) {
435
+ const { gameId, projectId, jobId, onProgress } = options;
436
+ let previousTransitionKey = null;
437
+ const startedAt = Date.now();
438
+ const timeoutMs = readCompileJobWaitTimeoutMs();
439
+ while (Date.now() - startedAt < timeoutMs) {
440
+ const {
441
+ data: job,
442
+ error,
443
+ response
444
+ } = await getJob({
445
+ path: { jobId }
446
+ });
447
+ if (error || !job) {
448
+ if (isTransientJobPollError(error, response)) {
449
+ await sleep(COMPILE_JOB_POLL_INTERVAL_MS);
450
+ continue;
451
+ }
452
+ throw toDreamboardApiError(error, response, "Failed to get job");
453
+ }
454
+ const transitionKey = `${job.status}:${job.phase ?? ""}`;
455
+ if (transitionKey !== previousTransitionKey) {
456
+ previousTransitionKey = transitionKey;
457
+ onProgress?.(job);
458
+ }
459
+ if (job.status === "COMPLETED" || job.status === "FAILED") {
460
+ const compiledResultId = job.createdCompiledResultId ?? job.createdAppScriptId;
461
+ if (compiledResultId) {
462
+ if (projectId) {
463
+ const compiledResult2 = await getProjectCompiledResultSdk(
464
+ projectId,
465
+ compiledResultId
466
+ );
467
+ return { job, compiledResult: compiledResult2 };
468
+ }
469
+ const compiledResult = await getCompiledResultSdk(
470
+ gameId,
471
+ compiledResultId
472
+ );
473
+ return { job, compiledResult };
474
+ }
475
+ const fallbackCompiledResult = await findFallbackCompiledResultForJob({
476
+ gameId,
477
+ projectId,
478
+ job
479
+ });
480
+ if (fallbackCompiledResult) {
481
+ return { job, compiledResult: fallbackCompiledResult };
482
+ }
483
+ throw new Error(formatTerminalCompileJobMessage(job));
484
+ }
485
+ if (job.status === "CANCELLED" || job.status === "INTERRUPTED") {
486
+ throw new Error(formatTerminalCompileJobMessage(job));
487
+ }
488
+ await sleep(COMPILE_JOB_POLL_INTERVAL_MS);
489
+ }
490
+ throw new Error(`Compile job ${jobId} did not complete in time.`);
491
+ }
492
+ function readCompileJobWaitTimeoutMs() {
493
+ const raw = process.env.DREAMBOARD_COMPILE_WAIT_TIMEOUT_MS;
494
+ if (!raw) return DEFAULT_COMPILE_JOB_WAIT_TIMEOUT_MS;
495
+ const parsed = Number(raw);
496
+ if (!Number.isFinite(parsed) || parsed <= 0) {
497
+ return DEFAULT_COMPILE_JOB_WAIT_TIMEOUT_MS;
498
+ }
499
+ return parsed;
500
+ }
501
+ function isTransientJobPollError(error, response) {
502
+ if (response) return false;
503
+ if (!error) return false;
504
+ if (error instanceof Error) {
505
+ return isTransientJobPollMessage(error.message);
506
+ }
507
+ if (typeof error === "object" && error !== null && "message" in error) {
508
+ return isTransientJobPollMessage(String(error.message));
509
+ }
510
+ return isTransientJobPollMessage(String(error));
511
+ }
512
+ function isTransientJobPollMessage(message) {
513
+ const normalized = message.toLowerCase();
514
+ return normalized.includes("fetch failed") || normalized.includes("network") || normalized.includes("timeout") || normalized.includes("econnreset") || normalized.includes("econnrefused") || normalized.includes("socket");
515
+ }
516
+
517
+ // src/services/api/project-api.ts
518
+ async function loadRemoteProjectIdentity() {
519
+ const [versionResponse, userResponse] = await Promise.all([
520
+ getApiVersion(),
521
+ getCurrentAuthUser()
522
+ ]);
523
+ if (versionResponse.error || !versionResponse.data) {
524
+ throw toDreamboardApiError(
525
+ versionResponse.error,
526
+ versionResponse.response,
527
+ "Failed to resolve backend deployment identity"
528
+ );
529
+ }
530
+ if (userResponse.error || !userResponse.data) {
531
+ throw toDreamboardApiError(
532
+ userResponse.error,
533
+ userResponse.response,
534
+ "Failed to resolve authenticated owner scope"
535
+ );
536
+ }
537
+ const deploymentId = versionResponse.data.deploymentId;
538
+ const ownerScopeId = userResponse.data.ownerScopeId;
539
+ return {
540
+ deploymentId,
541
+ ownerScopeId,
542
+ bindingKey: `${deploymentId}:${ownerScopeId}`
543
+ };
544
+ }
545
+ async function ensureProjectSdk(options) {
546
+ const { data, error, response } = await ensureProject({
547
+ path: { projectId: options.projectId },
548
+ body: {
549
+ slug: options.slug,
550
+ name: titleFromSlug(options.slug),
551
+ description: options.description ?? `Dreamboard workspace for ${options.slug}.`,
552
+ ...options.updateAlias ? { updateAlias: true } : {}
553
+ }
554
+ });
555
+ if (error || !data) {
556
+ throw toDreamboardApiError(error, response, "Failed to ensure project");
557
+ }
558
+ return data;
559
+ }
560
+ async function createGameRevisionSdk(options) {
561
+ const { data, error, response } = await createGameRevision({
562
+ path: { projectId: options.projectId },
563
+ body: options.request
564
+ });
565
+ if (error || !data) {
566
+ throw toDreamboardApiError(
567
+ error,
568
+ response,
569
+ "Failed to create game revision"
570
+ );
571
+ }
572
+ return data;
573
+ }
574
+
575
+ // src/services/api/preview-api.ts
576
+ async function uploadInitialProjectionSdk(gameId, projectionJson) {
577
+ const { error, response } = await uploadInitialProjection({
578
+ path: { gameId },
579
+ body: { projectionJson }
580
+ });
581
+ if (error) {
582
+ throw toDreamboardApiError(
583
+ error,
584
+ response,
585
+ "Failed to upload initial preview projection"
586
+ );
587
+ }
588
+ }
589
+
590
+ // src/services/api/source-revisions-api.ts
591
+ async function uploadProjectSourceBlobsSdk(projectId, blobs) {
592
+ try {
593
+ await uploadProjectSourceBlobs({ projectId, blobs });
594
+ } catch (error) {
595
+ if (error instanceof SourceBlobSessionRequestError) {
596
+ throw toDreamboardApiError(
597
+ error.apiError,
598
+ error.response,
599
+ error.message
600
+ );
601
+ }
602
+ throw error;
603
+ }
604
+ }
605
+
606
+ export {
607
+ defineCommand,
608
+ materializeSourceChangeOperations,
609
+ mapUpsertBlobContentsByContentHash,
610
+ CONFIG_FLAG_ARGS,
611
+ parseConfigFlags,
612
+ parseSyncCommandArgs,
613
+ parseCompileCommandArgs,
614
+ findProjectCompiledResultsForRevision,
615
+ getProjectCompiledResultSdk,
616
+ queueProjectRevisionCompileSdk,
617
+ waitForCompiledResultJobSdk,
618
+ loadRemoteProjectIdentity,
619
+ ensureProjectSdk,
620
+ createGameRevisionSdk,
621
+ uploadInitialProjectionSdk,
622
+ uploadProjectSourceBlobsSdk
623
+ };
624
+ //# sourceMappingURL=chunk-W3N3QJ4V.mjs.map