@playdrop/playdrop-cli 0.15.9 → 0.15.14

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 (40) hide show
  1. package/config/client-meta.json +2 -2
  2. package/dist/apps/index.d.ts +2 -2
  3. package/dist/apps/index.js +2 -1
  4. package/dist/apps/loadCheck.d.ts +2 -0
  5. package/dist/apps/loadCheck.js +49 -0
  6. package/dist/apps/upload.d.ts +38 -0
  7. package/dist/apps/upload.js +39 -32
  8. package/dist/commands/upload.js +1 -0
  9. package/dist/commands/worker.d.ts +3 -1
  10. package/dist/commands/worker.js +12 -3
  11. package/dist/index.js +7 -4
  12. package/node_modules/@playdrop/api-client/dist/client.d.ts +7 -12
  13. package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
  14. package/node_modules/@playdrop/api-client/dist/client.js +11 -0
  15. package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts +2 -2
  16. package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts.map +1 -1
  17. package/node_modules/@playdrop/api-client/dist/domains/admin.js +10 -2
  18. package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts +5 -11
  19. package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts.map +1 -1
  20. package/node_modules/@playdrop/api-client/dist/domains/payments.js +11 -4
  21. package/node_modules/@playdrop/api-client/dist/index.d.ts +7 -14
  22. package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
  23. package/node_modules/@playdrop/api-client/dist/index.js +8 -2
  24. package/node_modules/@playdrop/config/client-meta.json +2 -2
  25. package/node_modules/@playdrop/config/dist/src/creator-plans.d.ts +13 -0
  26. package/node_modules/@playdrop/config/dist/src/creator-plans.d.ts.map +1 -1
  27. package/node_modules/@playdrop/config/dist/src/creator-plans.js +20 -1
  28. package/node_modules/@playdrop/config/dist/test/creator-plans.test.js +15 -0
  29. package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
  30. package/node_modules/@playdrop/config/package.json +4 -0
  31. package/node_modules/@playdrop/types/dist/api.d.ts +52 -4
  32. package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
  33. package/node_modules/@playdrop/types/dist/api.js +25 -1
  34. package/node_modules/@playdrop/types/dist/index.d.ts +1 -0
  35. package/node_modules/@playdrop/types/dist/index.d.ts.map +1 -1
  36. package/node_modules/@playdrop/types/dist/index.js +3 -1
  37. package/node_modules/@playdrop/types/dist/locale.d.ts +10 -0
  38. package/node_modules/@playdrop/types/dist/locale.d.ts.map +1 -0
  39. package/node_modules/@playdrop/types/dist/locale.js +76 -0
  40. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "0.15.9",
2
+ "version": "0.15.14",
3
3
  "build": 1,
4
- "runtimeSdkVersion": "0.15.9",
4
+ "runtimeSdkVersion": "0.15.14",
5
5
  "runtimeSdkBuild": 1,
6
6
  "clients": {
7
7
  "all": {
@@ -4,7 +4,7 @@ import type { AppTask } from '../catalogue';
4
4
  import type { TaskCaptureSession } from '../appUrls';
5
5
  import { collectAppValidationWarnings, validateAppTask, runFormatScript } from './validate';
6
6
  import { buildApp, type AppBuildArtifacts } from './build';
7
- import { uploadApp, type AppUploadResult } from './upload';
7
+ import { prepareAppUploadFiles, uploadApp, type AppUploadResult } from './upload';
8
8
  export type AppPipelineResult = {
9
9
  artifacts: AppBuildArtifacts | null;
10
10
  upload: AppUploadResult;
@@ -30,4 +30,4 @@ export type AppPipelineOptions = {
30
30
  artifacts?: AppBuildArtifacts;
31
31
  };
32
32
  export declare function runAppPipeline(client: ApiClient, task: AppTask, options?: AppPipelineOptions): Promise<AppPipelineResult>;
33
- export { collectAppValidationWarnings, validateAppTask, buildApp, uploadApp, runFormatScript };
33
+ export { collectAppValidationWarnings, validateAppTask, buildApp, prepareAppUploadFiles, uploadApp, runFormatScript };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runFormatScript = exports.uploadApp = exports.buildApp = exports.validateAppTask = exports.collectAppValidationWarnings = void 0;
3
+ exports.runFormatScript = exports.uploadApp = exports.prepareAppUploadFiles = exports.buildApp = exports.validateAppTask = exports.collectAppValidationWarnings = void 0;
4
4
  exports.runAppPipeline = runAppPipeline;
5
5
  const validate_1 = require("./validate");
6
6
  Object.defineProperty(exports, "collectAppValidationWarnings", { enumerable: true, get: function () { return validate_1.collectAppValidationWarnings; } });
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "runFormatScript", { enumerable: true, get: funct
9
9
  const build_1 = require("./build");
10
10
  Object.defineProperty(exports, "buildApp", { enumerable: true, get: function () { return build_1.buildApp; } });
11
11
  const upload_1 = require("./upload");
12
+ Object.defineProperty(exports, "prepareAppUploadFiles", { enumerable: true, get: function () { return upload_1.prepareAppUploadFiles; } });
12
13
  Object.defineProperty(exports, "uploadApp", { enumerable: true, get: function () { return upload_1.uploadApp; } });
13
14
  const registration_1 = require("./registration");
14
15
  const loadCheck_1 = require("./loadCheck");
@@ -38,6 +38,7 @@ export declare function isSoftwareWebGlRenderer(renderer: string | null | undefi
38
38
  export declare function dispatchPlaytestTapeToFrame(page: Page, frame: Frame, surface: AppSurface, tape: AppPlaytestTape, hooks?: {
39
39
  onBeforeEvent?: (eventIndex: number, event: AppPlaytestTapeEvent) => void;
40
40
  }): Promise<void>;
41
+ export declare function verifyHostedEditorPhaseRoundTrip(page: Pick<Page, 'evaluate'>, frame: Pick<Frame, 'evaluate' | 'waitForFunction'>, timeoutMs: number): Promise<void>;
41
42
  export declare function formatHostedLoadCheckFailure(taskName: string, result: HostedLoadCheckResult, scope?: 'local' | 'staged' | 'editor' | 'final'): string;
42
43
  export declare function redactHostedLoadCheckSecrets(text: string, sourceUrl: string): string;
43
44
  export declare function runLocalHostedLoadCheck(input: {
@@ -72,6 +73,7 @@ export declare function runUploadedHostedLoadCheck(input: {
72
73
  playtestTape?: AppPlaytestTape;
73
74
  postReadyWaitMs?: number;
74
75
  phase?: 'play' | 'editor';
76
+ verifyEditorPhaseRoundTrip?: boolean;
75
77
  }): Promise<HostedLoadCheckResult>;
76
78
  export declare function comparePlaytestFrames(firstPath: string, secondPath: string, thresholds?: {
77
79
  meanDeltaMin: number;
@@ -10,6 +10,7 @@ exports.resolveLoadCheckSurface = resolveLoadCheckSurface;
10
10
  exports.cloneLoadCheckContextOptions = cloneLoadCheckContextOptions;
11
11
  exports.isSoftwareWebGlRenderer = isSoftwareWebGlRenderer;
12
12
  exports.dispatchPlaytestTapeToFrame = dispatchPlaytestTapeToFrame;
13
+ exports.verifyHostedEditorPhaseRoundTrip = verifyHostedEditorPhaseRoundTrip;
13
14
  exports.formatHostedLoadCheckFailure = formatHostedLoadCheckFailure;
14
15
  exports.redactHostedLoadCheckSecrets = redactHostedLoadCheckSecrets;
15
16
  exports.runLocalHostedLoadCheck = runLocalHostedLoadCheck;
@@ -417,6 +418,48 @@ async function findGameFrame(page, timeoutMs) {
417
418
  }
418
419
  return frame;
419
420
  }
421
+ async function verifyHostedEditorPhaseRoundTrip(page, frame, timeoutMs) {
422
+ const armReadySignal = async () => {
423
+ await frame.evaluate(() => {
424
+ const runtimeWindow = window;
425
+ const state = runtimeWindow.__playdropEditorPhaseCheck ?? {
426
+ installed: false,
427
+ signals: [],
428
+ };
429
+ state.signals = [];
430
+ runtimeWindow.__playdropEditorPhaseCheck = state;
431
+ if (state.installed) {
432
+ return;
433
+ }
434
+ state.installed = true;
435
+ window.addEventListener('playdrop:loading-state', (event) => {
436
+ const detail = event.detail;
437
+ if (detail?.status === 'ready') {
438
+ state.signals.push({ editor: detail.editor === true });
439
+ }
440
+ });
441
+ });
442
+ };
443
+ const changePhaseAndWait = async (phase, editor) => {
444
+ await armReadySignal();
445
+ await page.evaluate((nextPhase) => {
446
+ window.postMessage({ type: 'playdrop-studio-runtime-state', active: true, phase: nextPhase }, window.location.origin);
447
+ }, phase);
448
+ await frame.waitForFunction((expectedEditor) => {
449
+ const runtimeWindow = window;
450
+ return runtimeWindow.__playdropEditorPhaseCheck?.signals?.some((signal) => signal.editor === expectedEditor) === true;
451
+ }, editor, { timeout: timeoutMs });
452
+ };
453
+ try {
454
+ await changePhaseAndWait('play', false);
455
+ await changePhaseAndWait('editor', true);
456
+ }
457
+ catch (error) {
458
+ const detail = error instanceof Error ? error.message : String(error);
459
+ throw new Error('project_check_editor_phase_switch_failed: The hosted bundle must switch Editor to Playtest and back '
460
+ + `inside the existing runtime frame. ${detail}`);
461
+ }
462
+ }
420
463
  async function readWebGlRenderer(frame) {
421
464
  const renderer = await frame.evaluate(() => {
422
465
  const canvas = document.createElement('canvas');
@@ -696,6 +739,9 @@ async function runHostedLoadCheck(options) {
696
739
  if (isSoftwareWebGlRenderer(webglRenderer)) {
697
740
  throw new Error(`project_check_webgl_renderer_software: WebGL renderer is "${webglRenderer}". Real hardware acceleration is required.`);
698
741
  }
742
+ if (options.verifyEditorPhaseRoundTrip) {
743
+ await verifyHostedEditorPhaseRoundTrip(page, frame, readinessTimeoutMs);
744
+ }
699
745
  await saveGameFrameScreenshot(page, options.readyGameFrameScreenshotPath);
700
746
  if (options.playtestTape) {
701
747
  if (!options.playtestSurface) {
@@ -947,6 +993,7 @@ async function runUploadedHostedLoadCheck(input) {
947
993
  playtestTape: input.playtestTape,
948
994
  playtestSurface: captureSurface,
949
995
  postReadyWaitMs: input.postReadyWaitMs,
996
+ verifyEditorPhaseRoundTrip: input.verifyEditorPhaseRoundTrip,
950
997
  });
951
998
  }
952
999
  else if (anonymousExpectedState === 'login_required') {
@@ -980,6 +1027,7 @@ async function runUploadedHostedLoadCheck(input) {
980
1027
  playtestTape: input.playtestTape,
981
1028
  playtestSurface: captureSurface,
982
1029
  postReadyWaitMs: input.postReadyWaitMs,
1030
+ verifyEditorPhaseRoundTrip: input.verifyEditorPhaseRoundTrip,
983
1031
  });
984
1032
  }
985
1033
  }
@@ -997,6 +1045,7 @@ async function runUploadedHostedLoadCheck(input) {
997
1045
  playtestTape: input.playtestTape,
998
1046
  playtestSurface: captureSurface,
999
1047
  postReadyWaitMs: input.postReadyWaitMs,
1048
+ verifyEditorPhaseRoundTrip: input.verifyEditorPhaseRoundTrip,
1000
1049
  });
1001
1050
  }
1002
1051
  const recorded = await input.client.recordAppUploadLaunchCheck(input.creatorUsername, input.task.name, input.sessionId, {
@@ -25,4 +25,42 @@ export type AppUploadOptions = {
25
25
  playtestSmokeCheckRequired?: boolean;
26
26
  captureSession?: TaskCaptureSession | null;
27
27
  };
28
+ type PreparedSessionFile = {
29
+ fileKey: string;
30
+ file: File;
31
+ filename: string;
32
+ contentType: string;
33
+ sizeBytes: number;
34
+ sha256: string;
35
+ };
36
+ type PreparedOwnedAssetUpload = {
37
+ uploadKey: string;
38
+ runtimeKey?: string;
39
+ name: string;
40
+ displayName?: string;
41
+ description?: string;
42
+ category: string;
43
+ subcategory: string | null;
44
+ format: string;
45
+ visibility?: string;
46
+ license: string;
47
+ assetSpec?: string;
48
+ tags: string[];
49
+ shopListed?: boolean;
50
+ shopPriceCredits?: number;
51
+ files: Array<{
52
+ role: string;
53
+ file: File;
54
+ filename: string;
55
+ contentType: string;
56
+ sizeBytes: number;
57
+ sha256: string;
58
+ }>;
59
+ };
60
+ type PreparedAppUploadFiles = {
61
+ sessionFiles: PreparedSessionFile[];
62
+ ownedAssets: PreparedOwnedAssetUpload[];
63
+ };
64
+ export declare function prepareAppUploadFiles(task: AppTask, artifacts: AppBuildArtifacts | null): Promise<PreparedAppUploadFiles>;
28
65
  export declare function uploadApp(client: ApiClient, task: AppTask, artifacts: AppBuildArtifacts | null, options?: AppUploadOptions): Promise<AppUploadResult>;
66
+ export {};
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prepareAppUploadFiles = prepareAppUploadFiles;
3
4
  exports.uploadApp = uploadApp;
4
5
  const config_1 = require("@playdrop/config");
5
6
  const types_1 = require("@playdrop/types");
@@ -148,37 +149,20 @@ function pushPreparedArtifact(task, currentTotal, file, maxBytes, code, label) {
148
149
  const bytes = ensurePreparedArtifactSize(file, maxBytes, code, label);
149
150
  return accumulateUploadBytes(task.name, currentTotal, bytes);
150
151
  }
151
- async function uploadApp(client, task, artifacts, options) {
152
- // Version is required - no legacy fallback
153
- if (!task.version) {
154
- throw new Error(`Missing "version" field in catalogue.json for app "${task.name}".\n` +
155
- `Add a version field like "version": "1.0.0" to upload your app.`);
156
- }
157
- return uploadAppVersion(client, task, artifacts, options);
158
- }
159
- /**
160
- * Upload an app version using the versioned API.
161
- */
162
- async function uploadAppVersion(client, task, artifacts, options) {
163
- const creatorUsername = typeof options?.creatorUsername === 'string' ? options.creatorUsername.trim() : '';
164
- if (!creatorUsername) {
165
- throw new Error(`Missing creator username for app "${task.name}" upload.`);
166
- }
152
+ async function prepareAppUploadFiles(task, artifacts) {
167
153
  let totalUploadBytes = 0;
168
- const achievements = task.achievements ?? [];
169
- const leaderboards = task.leaderboards ?? [];
170
154
  const listing = task.listing;
171
- const preparedSessionFiles = [];
172
- const preparedOwnedAssets = await Promise.all(task.ownedAssets.map((ownedAsset) => prepareOwnedAssetUpload(ownedAsset)));
173
- for (const ownedAsset of preparedOwnedAssets) {
155
+ const sessionFiles = [];
156
+ const ownedAssets = await Promise.all(task.ownedAssets.map((ownedAsset) => prepareOwnedAssetUpload(ownedAsset)));
157
+ for (const ownedAsset of ownedAssets) {
174
158
  for (const file of ownedAsset.files) {
175
159
  totalUploadBytes = accumulateUploadBytes(task.name, totalUploadBytes, file.sizeBytes);
176
160
  }
177
161
  }
178
- for (const definition of achievements) {
162
+ for (const definition of task.achievements ?? []) {
179
163
  const prepared = createFileFromPath(definition.iconPath, 'image/png', config_1.MAX_VERSION_ICON_BYTES, 'achievement_icon_too_large', 'invalid_achievement_icon_content_type', `Achievement icon "${definition.key}"`, isPngSignature);
180
164
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
181
- preparedSessionFiles.push(await buildPreparedSessionFile(`achievementIcon:${definition.key}`, prepared.file));
165
+ sessionFiles.push(await buildPreparedSessionFile(`achievementIcon:${definition.key}`, prepared.file));
182
166
  }
183
167
  if (task.hostingMode === 'EXTERNAL') {
184
168
  // no hosted files
@@ -186,48 +170,70 @@ async function uploadAppVersion(client, task, artifacts, options) {
186
170
  else if (artifacts) {
187
171
  totalUploadBytes = pushPreparedArtifact(task, totalUploadBytes, artifacts.bundleFile, config_1.MAX_VERSION_BUNDLE_BYTES, 'bundle_too_large', 'Bundle');
188
172
  totalUploadBytes = pushPreparedArtifact(task, totalUploadBytes, artifacts.sourceFile, config_1.MAX_APP_SOURCE_BYTES, 'source_too_large', 'Source archive');
189
- preparedSessionFiles.push(await buildPreparedSessionFile('bundle', artifacts.bundleFile));
190
- preparedSessionFiles.push(await buildPreparedSessionFile('source', artifacts.sourceFile));
173
+ sessionFiles.push(await buildPreparedSessionFile('bundle', artifacts.bundleFile));
174
+ sessionFiles.push(await buildPreparedSessionFile('source', artifacts.sourceFile));
191
175
  }
192
176
  if (listing?.iconPath) {
193
177
  const prepared = createFileFromPath(listing.iconPath, 'image/png', config_1.MAX_VERSION_ICON_BYTES, 'icon_too_large', 'invalid_icon_content_type', 'Icon', isPngSignature);
194
178
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
195
- preparedSessionFiles.push(await buildPreparedSessionFile('icon', prepared.file));
179
+ sessionFiles.push(await buildPreparedSessionFile('icon', prepared.file));
196
180
  }
197
181
  if (listing?.heroPortraitPath) {
198
182
  const prepared = createFileFromPath(listing.heroPortraitPath, 'image/png', config_1.MAX_VERSION_HERO_BYTES, 'hero_portrait_too_large', 'invalid_hero_portrait_content_type', 'Hero portrait', isPngSignature);
199
183
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
200
- preparedSessionFiles.push(await buildPreparedSessionFile('heroPortrait', prepared.file));
184
+ sessionFiles.push(await buildPreparedSessionFile('heroPortrait', prepared.file));
201
185
  }
202
186
  if (listing?.heroLandscapePath) {
203
187
  const prepared = createFileFromPath(listing.heroLandscapePath, 'image/png', config_1.MAX_VERSION_HERO_BYTES, 'hero_landscape_too_large', 'invalid_hero_landscape_content_type', 'Hero landscape', isPngSignature);
204
188
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
205
- preparedSessionFiles.push(await buildPreparedSessionFile('heroLandscape', prepared.file));
189
+ sessionFiles.push(await buildPreparedSessionFile('heroLandscape', prepared.file));
206
190
  }
207
191
  for (let index = 0; index < (listing?.screenshotPortraitPaths ?? []).length; index += 1) {
208
192
  const filePath = listing.screenshotPortraitPaths[index];
209
193
  const prepared = createFileFromPath(filePath, 'image/png', config_1.MAX_VERSION_SCREENSHOT_BYTES, 'screenshot_portrait_too_large', 'invalid_screenshot_portrait_content_type', `Portrait screenshot ${index + 1}`, isPngSignature);
210
194
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
211
- preparedSessionFiles.push(await buildPreparedSessionFile(`screenshotsPortrait:${index}`, prepared.file));
195
+ sessionFiles.push(await buildPreparedSessionFile(`screenshotsPortrait:${index}`, prepared.file));
212
196
  }
213
197
  for (let index = 0; index < (listing?.screenshotLandscapePaths ?? []).length; index += 1) {
214
198
  const filePath = listing.screenshotLandscapePaths[index];
215
199
  const prepared = createFileFromPath(filePath, 'image/png', config_1.MAX_VERSION_SCREENSHOT_BYTES, 'screenshot_landscape_too_large', 'invalid_screenshot_landscape_content_type', `Landscape screenshot ${index + 1}`, isPngSignature);
216
200
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
217
- preparedSessionFiles.push(await buildPreparedSessionFile(`screenshotsLandscape:${index}`, prepared.file));
201
+ sessionFiles.push(await buildPreparedSessionFile(`screenshotsLandscape:${index}`, prepared.file));
218
202
  }
219
203
  for (let index = 0; index < (listing?.videoPortraitPaths ?? []).length; index += 1) {
220
204
  const filePath = listing.videoPortraitPaths[index];
221
205
  const prepared = createFileFromPath(filePath, 'video/mp4', config_1.MAX_VERSION_VIDEO_BYTES, 'video_portrait_too_large', 'invalid_video_portrait_content_type', `Portrait video ${index + 1}`, isMp4Signature);
222
206
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
223
- preparedSessionFiles.push(await buildPreparedSessionFile(`videosPortrait:${index}`, prepared.file));
207
+ sessionFiles.push(await buildPreparedSessionFile(`videosPortrait:${index}`, prepared.file));
224
208
  }
225
209
  for (let index = 0; index < (listing?.videoLandscapePaths ?? []).length; index += 1) {
226
210
  const filePath = listing.videoLandscapePaths[index];
227
211
  const prepared = createFileFromPath(filePath, 'video/mp4', config_1.MAX_VERSION_VIDEO_BYTES, 'video_landscape_too_large', 'invalid_video_landscape_content_type', `Landscape video ${index + 1}`, isMp4Signature);
228
212
  totalUploadBytes = pushPreparedFile(task.name, totalUploadBytes, prepared);
229
- preparedSessionFiles.push(await buildPreparedSessionFile(`videosLandscape:${index}`, prepared.file));
213
+ sessionFiles.push(await buildPreparedSessionFile(`videosLandscape:${index}`, prepared.file));
214
+ }
215
+ return { sessionFiles, ownedAssets };
216
+ }
217
+ async function uploadApp(client, task, artifacts, options) {
218
+ // Version is required - no legacy fallback
219
+ if (!task.version) {
220
+ throw new Error(`Missing "version" field in catalogue.json for app "${task.name}".\n` +
221
+ `Add a version field like "version": "1.0.0" to upload your app.`);
230
222
  }
223
+ return uploadAppVersion(client, task, artifacts, options);
224
+ }
225
+ /**
226
+ * Upload an app version using the versioned API.
227
+ */
228
+ async function uploadAppVersion(client, task, artifacts, options) {
229
+ const creatorUsername = typeof options?.creatorUsername === 'string' ? options.creatorUsername.trim() : '';
230
+ if (!creatorUsername) {
231
+ throw new Error(`Missing creator username for app "${task.name}" upload.`);
232
+ }
233
+ const achievements = task.achievements ?? [];
234
+ const leaderboards = task.leaderboards ?? [];
235
+ const listing = task.listing;
236
+ const { sessionFiles: preparedSessionFiles, ownedAssets: preparedOwnedAssets, } = await prepareAppUploadFiles(task, artifacts);
231
237
  const initializeRequest = {
232
238
  version: task.version,
233
239
  agentTaskId: options?.agentTaskId,
@@ -388,6 +394,7 @@ async function uploadAppVersion(client, task, artifacts, options) {
388
394
  currentUser: options?.user ?? null,
389
395
  captureSession: options?.captureSession,
390
396
  phase: 'editor',
397
+ verifyEditorPhaseRoundTrip: true,
391
398
  });
392
399
  if (editorLoadCheck.status !== 'PASSED') {
393
400
  throw new Error((0, loadCheck_1.formatHostedLoadCheckFailure)(task.name, editorLoadCheck, 'editor'));
@@ -1387,6 +1387,7 @@ async function prepareWorkerAppProject(input) {
1387
1387
  // update, upload-session creation, file upload, or version creation.
1388
1388
  async function preflightWorkerAppProject(input) {
1389
1389
  const prepared = await prepareWorkerAppProject(input);
1390
+ await (0, apps_1.prepareAppUploadFiles)(prepared.task, prepared.artifacts);
1390
1391
  return {
1391
1392
  appName: prepared.task.name,
1392
1393
  creatorUsername: prepared.creatorUsername,
@@ -17,7 +17,8 @@ export declare function buildCreatorRecoveryPrompt(input: {
17
17
  }): string;
18
18
  export declare function buildGameEvalRetryPrompt(prompt: string): string;
19
19
  export declare const WORKER_SESSION_EXPIRED_MESSAGE = "worker session expired: run \"playdrop auth login\" and start the worker again";
20
- export declare const WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = "worker_context_command_not_allowed: inside a PlayDrop worker task only task progress, task claim-slug, task upload/done/fail, assigned app scaffolding, project validation/build/dev/check/capture, read-only help/catalogue/documentation lookup, and PlayDrop AI generation are permitted.";
20
+ export declare const WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = "worker_context_command_not_allowed: inside a PlayDrop worker task only task progress, task claim-slug, task upload/done/fail, assigned app scaffolding, project build/dev/check/capture, read-only help/catalogue/documentation lookup, and PlayDrop AI generation are permitted.";
21
+ export declare const WORKER_CONTEXT_PROJECT_VALIDATE_NOT_ALLOWED_MESSAGE = "worker_context_project_validate_not_allowed: \"playdrop project validate\" is not available inside a PlayDrop worker task. Run \"playdrop task upload --preflight-only\" as the sole pre-upload validation gate.";
21
22
  type WorkerStartOptions = {
22
23
  env?: string;
23
24
  once?: boolean;
@@ -196,6 +197,7 @@ export declare function allocateWorkerDevPort(input: {
196
197
  maxParallelTasks?: number;
197
198
  }): number;
198
199
  export declare function isWorkerContextCommandAllowed(argv: string[]): boolean;
200
+ export declare function resolveWorkerContextCommandBlockMessage(argv: string[]): string | null;
199
201
  export declare function resolveWorkerExecutionTargetFromRole(role: unknown): AgentExecutionTarget;
200
202
  export declare function normalizeWorkerTaskAssignmentV2(claim: WorkerClaimAgentTaskResponse): WorkerTaskAssignmentV2 | null;
201
203
  export declare function nextClaimBackoffMs(currentMs: number): number;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.WORKER_TASK_WORKSPACE_RETENTION = exports.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = exports.WORKER_SESSION_EXPIRED_MESSAGE = exports.runLoggedProcess = exports.readEnvBoolean = exports.readCodexSandboxMode = exports.readCodexRolloutTokenUsageForThread = exports.extractCodexTokensUsed = exports.extractCodexThreadId = exports.extractClaudeSessionId = exports.extractCodexRolloutTokenUsage = exports.extractAgentTokenUsage = exports.DEFAULT_WORKER_TOKEN_CAP = exports.DEFAULT_CREATOR_UPLOAD_RECOVERY_TIMEOUT_MS = exports.DEFAULT_CREATOR_AGENT_TIMEOUT_MS = exports.DEFAULT_CODEX_TIMEOUT_MS = exports.buildWorkerChildEnv = exports.buildPlaywrightMcpCommand = exports.buildCodexExecArgs = exports.buildCleanRoomChildEnv = exports.buildClaudePermissionSettings = exports.buildClaudeExecArgs = exports.assertWorkerTokenUsageWithinCap = void 0;
6
+ exports.WORKER_TASK_WORKSPACE_RETENTION = exports.WORKER_CONTEXT_PROJECT_VALIDATE_NOT_ALLOWED_MESSAGE = exports.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = exports.WORKER_SESSION_EXPIRED_MESSAGE = exports.runLoggedProcess = exports.readEnvBoolean = exports.readCodexSandboxMode = exports.readCodexRolloutTokenUsageForThread = exports.extractCodexTokensUsed = exports.extractCodexThreadId = exports.extractClaudeSessionId = exports.extractCodexRolloutTokenUsage = exports.extractAgentTokenUsage = exports.DEFAULT_WORKER_TOKEN_CAP = exports.DEFAULT_CREATOR_UPLOAD_RECOVERY_TIMEOUT_MS = exports.DEFAULT_CREATOR_AGENT_TIMEOUT_MS = exports.DEFAULT_CODEX_TIMEOUT_MS = exports.buildWorkerChildEnv = exports.buildPlaywrightMcpCommand = exports.buildCodexExecArgs = exports.buildCleanRoomChildEnv = exports.buildClaudePermissionSettings = exports.buildClaudeExecArgs = exports.assertWorkerTokenUsageWithinCap = void 0;
7
7
  exports.usesCreatorRecovery = usesCreatorRecovery;
8
8
  exports.buildDeterministicReleaseSmokeArtifact = buildDeterministicReleaseSmokeArtifact;
9
9
  exports.buildCreatorRecoveryPrompt = buildCreatorRecoveryPrompt;
@@ -11,6 +11,7 @@ exports.buildGameEvalRetryPrompt = buildGameEvalRetryPrompt;
11
11
  exports.resolveInitialCreatorProgress = resolveInitialCreatorProgress;
12
12
  exports.allocateWorkerDevPort = allocateWorkerDevPort;
13
13
  exports.isWorkerContextCommandAllowed = isWorkerContextCommandAllowed;
14
+ exports.resolveWorkerContextCommandBlockMessage = resolveWorkerContextCommandBlockMessage;
14
15
  exports.resolveWorkerExecutionTargetFromRole = resolveWorkerExecutionTargetFromRole;
15
16
  exports.normalizeWorkerTaskAssignmentV2 = normalizeWorkerTaskAssignmentV2;
16
17
  exports.nextClaimBackoffMs = nextClaimBackoffMs;
@@ -222,7 +223,6 @@ const WORKER_CONTEXT_ALLOWED_COMMANDS = [
222
223
  ['review', 'validate-result'],
223
224
  ['review', 'compose-evidence'],
224
225
  ['review', 'rating-card'],
225
- ['project', 'validate'],
226
226
  ['project', 'build'],
227
227
  ['project', 'dev'],
228
228
  ['project', 'check'],
@@ -240,7 +240,8 @@ const WORKER_CONTEXT_ALLOWED_COMMANDS = [
240
240
  ['ai', 'jobs', 'detail'],
241
241
  ['ai', 'generations'],
242
242
  ];
243
- exports.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = 'worker_context_command_not_allowed: inside a PlayDrop worker task only task progress, task claim-slug, task upload/done/fail, assigned app scaffolding, project validation/build/dev/check/capture, read-only help/catalogue/documentation lookup, and PlayDrop AI generation are permitted.';
243
+ exports.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = 'worker_context_command_not_allowed: inside a PlayDrop worker task only task progress, task claim-slug, task upload/done/fail, assigned app scaffolding, project build/dev/check/capture, read-only help/catalogue/documentation lookup, and PlayDrop AI generation are permitted.';
244
+ exports.WORKER_CONTEXT_PROJECT_VALIDATE_NOT_ALLOWED_MESSAGE = 'worker_context_project_validate_not_allowed: "playdrop project validate" is not available inside a PlayDrop worker task. Run "playdrop task upload --preflight-only" as the sole pre-upload validation gate.';
244
245
  function resolveInitialCreatorProgress(kind, creationRecovery = false) {
245
246
  if (creationRecovery) {
246
247
  return null;
@@ -297,6 +298,14 @@ function isWorkerContextCommandAllowed(argv) {
297
298
  }
298
299
  return isAssignedAppScaffoldCommandAllowed(argv);
299
300
  }
301
+ function resolveWorkerContextCommandBlockMessage(argv) {
302
+ if (argv[0] === 'project' && argv[1] === 'validate') {
303
+ return exports.WORKER_CONTEXT_PROJECT_VALIDATE_NOT_ALLOWED_MESSAGE;
304
+ }
305
+ return isWorkerContextCommandAllowed(argv)
306
+ ? null
307
+ : exports.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE;
308
+ }
300
309
  function readWorkerContextForPolicy() {
301
310
  try {
302
311
  return readTaskContextFile();
package/dist/index.js CHANGED
@@ -49,11 +49,14 @@ const notes_1 = require("./commands/notes");
49
49
  const worker_1 = require("./commands/worker");
50
50
  const messages_1 = require("./messages");
51
51
  // Restricted shim: inside a worker task workspace only task-scoped commands,
52
- // local validation/run helpers, safe read-only lookups, and AI generation are
52
+ // local build/run helpers, safe read-only lookups, and AI generation are
53
53
  // permitted. Worker lease credentials are never exposed to the agent process.
54
- if (process.env.PLAYDROP_WORKER_CONTEXT === '1' && !(0, worker_1.isWorkerContextCommandAllowed)(process.argv.slice(2))) {
55
- console.error(worker_1.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE);
56
- process.exit(1);
54
+ if (process.env.PLAYDROP_WORKER_CONTEXT === '1') {
55
+ const workerContextBlockMessage = (0, worker_1.resolveWorkerContextCommandBlockMessage)(process.argv.slice(2));
56
+ if (workerContextBlockMessage) {
57
+ console.error(workerContextBlockMessage);
58
+ process.exit(1);
59
+ }
57
60
  }
58
61
  function printRemovedCommandHint(command) {
59
62
  const replacements = {
@@ -1,4 +1,4 @@
1
- import type { AcquisitionAttributionRequest, AcquisitionAttributionResponse, AbortAppUploadResponse, AbortAssetPackUploadResponse, AdInterstitialShowResponse, AdLoadRequest, AdLoadResponse, AdRewardedShowResponse, AdShowRequest, AdminAgentTaskDetailResponse, AdminAgentTaskTranscriptResponse, AdminAgentTasksResponse, AdminAgentWorkersStatusResponse, AdminAppPlayerMetaResponse, AdminAppPlayerMetaUserResponse, AdminAppVersionReviewsListResponse, AdminAppsListResponse, AdminCreatorEngagementExecutionsResponse, AdminCreatorEngagementRulePreviewRequest, AdminCreatorEngagementRulePreviewResponse, AdminCreatorEngagementRulesResponse, AdminCreatorEngagementUserResponse, AdminCreatorSubscriptionsResponse, AdminCreditTransactionsResponse, AdminCreatorAcquisitionAnalyticsRequest, AdminPaidAcquisitionAnalyticsRequest, AdminEnqueueNextAppVersionReviewTaskResponse, AdminFeedbackListResponse, AdminFeedbackResponse, AdminGameCollectionCandidatesResponse, AdminGameCollectionResponse, AdminGameCollectionsResponse, AdminMutateAchievementStateRequest, AdminMutateAchievementStateResponse, AdminMutateLeaderboardScoreRequest, AdminMutateLeaderboardScoreResponse, AdminPaymentDetailResponse, AdminPaymentsListResponse, AdminPlatformAnalyticsRequest, AdminPlatformAnalyticsResponse, AdminTractionAnalyticsRequest, AdminRefundPaymentRequest, AdminRetirePlayerMetaDefinitionResponse, AdminTagGroupResponse, AdminTagGroupsResponse, AdminTagResponse, AdminUpdateAppRequest, AdminUpdateAppResponse, AdminUpdateAppVersionReviewRequest, AdminUpdateAppVersionReviewResponse, AdminUserResponse, AgentTaskAttachmentUploadResponse, AgentTaskAvailabilityResponse, AgentTaskCreatorFeedbackStatus, AgentTaskDetailResponse, AgentTaskEventsResponse, AgentTaskKind, AgentTaskNewGameSuggestionsResponse, AgentTasksResponse, AiGenerationDetailResponse, AiGenerationsResponse, ApiKeyLoginRequest, AppAccessTokenResponse, AppAgentTaskResponse, AppBrowseRequest, AppDetailRequest, AppDetailResponse, AppLogEntryRequest, AppLogEntryResponse, AppListingDraftMediaSlot, AppListingDraftResponse, AppMoreCollectionKey, AppMoreCollectionPage, AppMoreCollectionRequest, AppMoreCollectionsRequest, AppMoreCollectionsResponse, AppRuntimeAssetsResponse, AppAuthMode, AppSourceBundleResponse, AppType, AppUploadLaunchCheckPreviewResponse, AppVersionDetailResponse, AppVersionVisibility, PublishAppListingDraftResponse, AppTweaksSnapshot, CreatorNotesClearResponse, CreatorNotesResponse, CreateCreatorPlanGrantRequest, CreatorPlanGrantMutationResponse, TweakValues, UpdateAppListingDraftRequest, AppVersionsListResponse, AppleCreditPackFulfillmentRequest, AppleLinkRequest, AppleLinkResponse, AppleNativeChallengeResponse, AppleOAuthHandoffExchangeRequest, AppleOAuthHandoffExchangeResponse, AppleOAuthLinkStartRequest, AppleOAuthLinkStartResponse, ApplePendingSignupResponse, ApplePushDeviceRequest, ApplePushDeviceStatusResponse, AppleSignInRequest, AppleSignInResponse, AppsListResponse, AssetBrowseKind, AssetCategoriesResponse, AssetCategory, AssetDetailResponse, AssetFormat, AssetListResponse, AssetListSort, AssetPackDetailResponse, AssetPackListResponse, AssetPackListSort, AssetPackSourceBundleResponse, AssetPackVersionsListResponse, AssetPurchaseRequest, AssetSourceBundleResponse, AssetSourceKind, AssetSpecAppsListResponse, AssetSpecAssetsListResponse, AssetSpecDetailResponse, AssetSpecListResponse, AssetSpecListSort, AssetSpecVersionResponseEnvelope, AssetSpecVersionsListResponse, AssetVersionsListResponse, AssetVisibility, BatchCreateUsersResponse, BatchUpsertNodeRelationsRequest, BatchUpsertNodeRelationsResponse, BoostActivationRequest, BoostBalanceResponse, BoostHistoryResponse, BoostPurchaseRequest, BoostPurchaseResponse, BoostReportQuery, BoostReportResponse, BoostStatusResponse, BootstrapResponse, CancelAgentTaskResponse, ChangePasswordRequest, ChangePasswordResponse, ClaimFreeCreditRewardResponse, ClearAgentTaskResponse, CliApiKeyStatusResponse, CliApiTokenSecretResponse, CliApiTokensResponse, CliLoginApproveRequest, CliLoginApproveResponse, CliLoginPollRequest, CliLoginPollResponse, CliLoginStartResponse, CliLoginStatusResponse, CliWebLaunchStartRequest, CliWebLaunchStartResponse, CompleteAppleSignupRequest, CompleteAppleSignupResponse, CompleteGoogleSignupRequest, CompleteGoogleSignupResponse, CompleteXSignupRequest, CompleteXSignupResponse, NativeOAuthHandoffExchangeRequest, NativeOAuthHandoffExchangeResponse, NativeOAuthLinkStartRequest, NativeOAuthLinkStartResponse, ContentCommentsResponse, ContentLicense, ContentRemixRelationsResponse, CreateAdminGameCollectionRequest, CreateAppAgentTaskRequest, CreateAppAgentTaskResponse, CreateAppRequest, CreateAppResponse, CreateAssetSpecVersionResponse, CreateAssetVersionResponse, CreateCliApiKeyResponse, CreateCliApiTokenRequest, CreateCommentReportRequest, CreateContentCommentRequest, CreateContentCommentResponse, CreateContentReportRequest, CreateCreatorReportRequest, CreateGameEvalAgentTaskRequest, CreateGameEvalAgentTaskResponse, CreateNewGameAgentTaskRequest, CreateNewGameAgentTaskResponse, CreateStaticGameAgentTaskRequest, CreateStaticGameAgentTaskResponse, CreateRemixGameAgentTaskRequest, CreateRemixGameAgentTaskResponse, CreateTagGroupRequest, CreateTagRequest, CreateUserRequest, CreateUserResponse, CreatorAppsBrowseRequest, CreatorBlockMutationResponse, CreatorEarningsResponse, CreatorEngagementRuleExecutionStatus, CreatorAcquisitionAnalyticsResponse, PaidAcquisitionAnalyticsResponse, CreatorFollowMutationResponse, CreatorGameCreatorFeedbackStatusResponse, CreatorGameShareResponse, CreatorGameStatusResponse, CreatorGameVersionsResponse, CreatorGamesListResponse, CreationConversationResponse, CreditPackCheckoutSessionRequest, CreditPackCheckoutSessionResponse, CreditPackCheckoutStatusResponse, CreatorPlanCheckoutSessionResponse, CreatorPlanCheckoutSessionStatusResponse, CreatorPlanPortalSessionResponse, CreatorPlanState, CreatorPlanTier, CreditPackResponse, CreditPacksResponse, DeleteAdminGameCollectionResponse, DeleteAdminUserResponse, DeleteAppResponse, DeleteAssetPackResponse, DeleteAssetPackVersionResponse, DeleteAssetResponse, DeleteAssetSpecResponse, DeleteAssetSpecVersionResponse, DeleteAssetVersionResponse, DeleteCliApiTokenResponse, DeleteContentCommentResponse, DeleteFeedbackResponse, DeleteMyAccountRequest, DeleteMyAccountResponse, DeleteOwnedCustomAssetResponse, DeleteVersionResponse, DevAppAccessTokenResponse, DevPlayerResetResponse, DislikedItemMutationResponse, EmailPreferencesResponse, EmailUnsubscribeResponse, FeedbackCategory, FeedbackClient, FeedbackListResponse, FeedbackStatus, FetchHomeOptions, FinalizeAppUploadResponse, FinalizeAppUploadRequest, FinalizeAssetPackUploadResponse, FirebasePushDeviceRequest, FirebasePushDeviceStatusResponse, GameplaySessionResponse, GameplaySessionActivityRequest, GameplaySessionStartRequest, FollowingCreatorsResponse, FollowingFeedResponse, FollowingFeedSection, FollowingSort, FreeCreditsResponse, GetAchievementResponse, GetLeaderboardResponse, GoogleAppleLinkRequest, GoogleAppleLinkResponse, GoogleAppleSignInRequest, GoogleAppleSignInResponse, GoogleCreditPackFulfillmentRequest, GoogleOneTapExchangeRequest, GoogleOneTapExchangeResponse, GooglePendingSignupResponse, HomeCollectionPageResponse, HomeResponse, IapPurchaseRequest, IapPurchaseResponse, IapReceiptListParams, IapReceiptResponse, IapReceiptsResponse, InitializeAppUploadRequest, InitializeAppUploadResponse, InitializeAssetPackUploadRequest, InitializeAssetPackUploadResponse, InvitePreviewResponse, LibraryCategory, LibraryResponse, LibrarySort, LikedItemMutationResponse, ListAchievementsResponse, ListLeaderboardsResponse, ListOwnedCustomAssetsResponse, LoadOwnedCustomAssetResponse, LoginRequest, LoginResponse, LogoutResponse, MeAgentWorkersResponse, MeResponse, MobileCreditPackFulfillmentResponse, ModerationReportResponse, MutateOwnedCustomAssetRequest, MutateOwnedCustomAssetResponse, MyAchievementsResponse, MyAppsResponse, MyInviteCodeResponse, MyLeaderboardsResponse, NotificationReadResponse, NotificationStatus, NotificationsResponse, OwnedProfileAssetsResponse, PaymentProvider, PaymentStatus, PrivacyExportResponse, PublicEmailPreferencesResponse, PublicEmailPreferencesUpdateRequest, PurchaseResponse, PushSubscriptionMutationResponse, RecordAppUploadLaunchCheckRequest, RecordAppUploadLaunchCheckResponse, RecordAppUploadCausalCheckRequest, RecordAppUploadCausalCheckResponse, RecordAppUploadMediaCaptureRequest, RecordAppUploadMediaCaptureResponse, RegisterRequest, RegisterResponse, RemixScaffoldResponse, ResolveRuntimeAssetsRequest, ResolveRuntimeAssetsResponse, RetryAgentTaskResponse, ReviewState, SavedItemKind, SavedItemMutationResponse, SearchRequest, SearchResponse, SearchSuggestRequest, SearchSuggestResponse, SetAchievementProgressRequest, SetAchievementProgressResponse, SetProfileAssetRequest, SetProfileAssetResponse, ShopResponse, StarterProfileAssetsResponse, SubmitFeedbackRequest, SubmitFeedbackResponse, SubmitLeaderboardScoreRequest, SubmitLeaderboardScoreResponse, TagDetailResponse, TagDirectoryResponse, TagGroupDetailResponse, TagGroupSort, TagListResponse, TemplateScaffoldResponse, TrackEngagementEventRequest, TrackEngagementEventResponse, TractionAnalyticsResponse, TransactionsResponse, UnlinkGoogleResponse, UnlinkXResponse, UnlockAchievementResponse, UpdateAdminFeedbackRequest, UpdateAdminFeedbackResponse, UpdateAdminGameCollectionGamesRequest, UpdateAdminGameCollectionRequest, UpdateAdminUserRequest, UpdateAppRequest, UpdateAppResponse, UpdateAssetPackRequest, UpdateAssetPackResponse, UpdateAssetPackVersionRequest, UpdateAssetPackVersionResponse, UpdateAssetRequest, UpdateAssetResponse, UpdateAssetSpecVersionResponse, UpdateAssetVersionRequest, UpdateAssetVersionResponse, UpdateProfileRequest, UpdateProfileResponse, UpdateTagGroupRequest, UpdateTagRequest, UpdateUserCommunicationPreferencesRequest, UpdateVersionResponse, UploadAppSessionFileResponse, UploadAppSessionOwnedAssetResponse, UploadAssetPackSessionAssetResponse, UploadAssetPackSessionMediaResponse, UpsertWebPushSubscriptionRequest, UserDetailResponse, UsernameAvailableResponse, UsersListResponse, WebPushConfigResponse, WebPushSubscriptionStatusResponse, WorkerAgentTaskAttemptUnavailableRequest, WorkerAgentTaskAttemptUnavailableResponse, WorkerClaimAgentTaskRequest, WorkerClaimAgentTaskResponse, WorkerClaimAgentTaskSlugRequest, WorkerClaimAgentTaskSlugResponse, WorkerCompleteAgentTaskRequest, WorkerCompleteReleaseSmokeRequest, WorkerCreateAgentTaskEventRequest, WorkerCreateAgentTaskEventResponse, WorkerCreateAgentTaskTranscriptChunkRequest, WorkerCreateAgentTaskTranscriptChunkResponse, WorkerFailAgentTaskRequest, WorkerHeartbeatAgentTaskRequest, WorkerHeartbeatAgentTaskResponse, WorkerPresenceRequest, WorkerPresenceResponse, RegisterAgentBundleRequest, RegisterAgentBundleResponse, WorkerRecordAgentTaskRunTelemetryRequest, WorkerRecordAgentTaskRunTelemetryResponse, WorkerSubmitAgentTaskEvalRequest, WorkerSubmitAgentTaskEvalResponse, WorkerSubmitAgentTaskReviewRequest, WorkerSubmitAgentTaskReviewResponse, WorkerAgentTaskMaterialResponse, WorkerUpdateIntentRequest, WorkerUpdateIntentResponse, XPendingSignupResponse } from '@playdrop/types';
1
+ import type { AcquisitionAttributionRequest, AcquisitionAttributionResponse, AbortAppUploadResponse, AbortAssetPackUploadResponse, AdInterstitialShowResponse, AdLoadRequest, AdLoadResponse, AdRewardedShowResponse, AdShowRequest, AdminAgentTaskDetailResponse, AdminAgentTaskTranscriptResponse, AdminAgentTasksResponse, AdminAgentWorkersStatusResponse, AdminAppPlayerMetaResponse, AdminAppPlayerMetaUserResponse, AdminAppVersionReviewsListResponse, AdminAppsListResponse, AdminCreatorEngagementExecutionsResponse, AdminCreatorEngagementRulePreviewRequest, AdminCreatorEngagementRulePreviewResponse, AdminCreatorEngagementRulesResponse, AdminCreatorEngagementUserResponse, AdminCreatorSubscriptionsResponse, AdminCreditTransactionsResponse, AdminCreatorAcquisitionAnalyticsRequest, AdminPaidAcquisitionAnalyticsRequest, AdminEnqueueNextAppVersionReviewTaskResponse, AdminFeedbackListResponse, AdminFeedbackResponse, AdminGameCollectionCandidatesResponse, AdminGameCollectionResponse, AdminGameCollectionsResponse, AdminMutateAchievementStateRequest, AdminMutateAchievementStateResponse, AdminMutateLeaderboardScoreRequest, AdminMutateLeaderboardScoreResponse, AdminPaymentDetailResponse, AdminPaymentsListResponse, AdminPlatformAnalyticsRequest, AdminPlatformAnalyticsResponse, AdminTractionAnalyticsRequest, AdminRefundPaymentRequest, AdminRetirePlayerMetaDefinitionResponse, AdminTagGroupResponse, AdminTagGroupsResponse, AdminTagResponse, AdminUpdateAppRequest, AdminUpdateAppResponse, AdminUpdateAppVersionReviewRequest, AdminUpdateAppVersionReviewResponse, AdminUserResponse, AgentTaskAttachmentUploadResponse, AgentTaskAvailabilityResponse, AgentTaskCreatorFeedbackStatus, AgentTaskDetailResponse, AgentTaskEventsResponse, AgentTaskKind, AgentTaskNewGameSuggestionsResponse, AgentTasksResponse, AiGenerationDetailResponse, AiGenerationsResponse, ApiKeyLoginRequest, AppAccessTokenResponse, AppAgentTaskResponse, AppBrowseRequest, AppDetailRequest, AppDetailResponse, AppLogEntryRequest, AppLogEntryResponse, AppListingDraftMediaSlot, AppListingDraftResponse, AppMoreCollectionKey, AppMoreCollectionPage, AppMoreCollectionRequest, AppMoreCollectionsRequest, AppMoreCollectionsResponse, AppRuntimeAssetsResponse, AppAuthMode, AppSourceBundleResponse, AppType, AppUploadLaunchCheckPreviewResponse, AppVersionDetailResponse, AppVersionVisibility, PublishAppListingDraftResponse, AppTweaksSnapshot, CreatorNotesClearResponse, CreatorNotesResponse, CreateCreatorPlanGrantRequest, CreatorPlanGrantMutationResponse, TweakValues, UpdateAppListingDraftRequest, AppVersionsListResponse, AppleCreditPackFulfillmentRequest, AppleLinkRequest, AppleLinkResponse, AppleNativeChallengeResponse, AppleOAuthHandoffExchangeRequest, AppleOAuthHandoffExchangeResponse, AppleOAuthLinkStartRequest, AppleOAuthLinkStartResponse, ApplePendingSignupResponse, ApplePushDeviceRequest, ApplePushDeviceStatusResponse, AppleSignInRequest, AppleSignInResponse, AppsListResponse, AssetBrowseKind, AssetCategoriesResponse, AssetCategory, AssetDetailResponse, AssetFormat, AssetListResponse, AssetListSort, AssetPackDetailResponse, AssetPackListResponse, AssetPackListSort, AssetPackSourceBundleResponse, AssetPackVersionsListResponse, AssetPurchaseRequest, AssetSourceBundleResponse, AssetSourceKind, AssetSpecAppsListResponse, AssetSpecAssetsListResponse, AssetSpecDetailResponse, AssetSpecListResponse, AssetSpecListSort, AssetSpecVersionResponseEnvelope, AssetSpecVersionsListResponse, AssetVersionsListResponse, AssetVisibility, BatchCreateUsersResponse, BatchUpsertNodeRelationsRequest, BatchUpsertNodeRelationsResponse, BoostActivationRequest, BoostBalanceResponse, BoostHistoryResponse, BoostPurchaseRequest, BoostPurchaseResponse, BoostReportQuery, BoostReportResponse, BoostStatusResponse, BootstrapResponse, CancelAgentTaskResponse, ChangePasswordRequest, ChangePasswordResponse, ClaimFreeCreditRewardResponse, ClearAgentTaskResponse, CliApiKeyStatusResponse, CliApiTokenSecretResponse, CliApiTokensResponse, CliLoginApproveRequest, CliLoginApproveResponse, CliLoginPollRequest, CliLoginPollResponse, CliLoginStartResponse, CliLoginStatusResponse, CliWebLaunchStartRequest, CliWebLaunchStartResponse, CompleteAppleSignupRequest, CompleteAppleSignupResponse, CompleteGoogleSignupRequest, CompleteGoogleSignupResponse, CompleteXSignupRequest, CompleteXSignupResponse, NativeOAuthHandoffExchangeRequest, NativeOAuthHandoffExchangeResponse, NativeOAuthLinkStartRequest, NativeOAuthLinkStartResponse, ContentCommentsResponse, ContentLicense, ContentRemixRelationsResponse, CreateAdminGameCollectionRequest, CreateAppAgentTaskRequest, CreateAppAgentTaskResponse, CreateAppRequest, CreateAppResponse, CreateAssetSpecVersionResponse, CreateAssetVersionResponse, CreateCliApiKeyResponse, CreateCliApiTokenRequest, CreateCommentReportRequest, CreateContentCommentRequest, CreateContentCommentResponse, CreateContentReportRequest, CreateCreatorReportRequest, CreateGameEvalAgentTaskRequest, CreateGameEvalAgentTaskResponse, CreateNewGameAgentTaskRequest, CreateNewGameAgentTaskResponse, CreateStaticGameAgentTaskRequest, CreateStaticGameAgentTaskResponse, CreateRemixGameAgentTaskRequest, CreateRemixGameAgentTaskResponse, CreateTagGroupRequest, CreateTagRequest, CreateUserRequest, CreateUserResponse, CreatorAppsBrowseRequest, CreatorBlockMutationResponse, CreatorEarningsResponse, CreatorEngagementRuleExecutionStatus, CreatorAcquisitionAnalyticsResponse, PaidAcquisitionAnalyticsResponse, CreatorFollowMutationResponse, CreatorGameCreatorFeedbackStatusResponse, CreatorGameShareResponse, CreatorGameStatusResponse, CreatorGameVersionsResponse, CreatorGamesListResponse, CreationConversationResponse, CreditPackCheckoutSessionRequest, CreditPackCheckoutSessionResponse, CreditPackCheckoutStatusResponse, CreatorPlanCheckoutSessionResponse, CreatorPlanCheckoutSessionStatusResponse, CreatorPlanPortalSessionResponse, CreatorPlanSessionRequest, CreatorPlanState, CreatorPlanTier, CreditPackResponse, CreditPacksResponse, DeleteAdminGameCollectionResponse, DeleteAdminUserResponse, DeleteAppResponse, DeleteAssetPackResponse, DeleteAssetPackVersionResponse, DeleteAssetResponse, DeleteAssetSpecResponse, DeleteAssetSpecVersionResponse, DeleteAssetVersionResponse, DeleteCliApiTokenResponse, DeleteContentCommentResponse, DeleteFeedbackResponse, DeleteMyAccountRequest, DeleteMyAccountResponse, DeleteOwnedCustomAssetResponse, DeleteVersionResponse, DevAppAccessTokenResponse, DevPlayerResetResponse, DislikedItemMutationResponse, EmailPreferencesResponse, EmailUnsubscribeResponse, FeedbackCategory, FeedbackClient, FeedbackListResponse, FeedbackStatus, FetchAdminUsersOptions, FetchHomeOptions, FinalizeAppUploadResponse, FinalizeAppUploadRequest, FinalizeAssetPackUploadResponse, FirebasePushDeviceRequest, FirebasePushDeviceStatusResponse, GameplaySessionResponse, GameplaySessionActivityRequest, GameplaySessionStartRequest, FollowingCreatorsResponse, FollowingFeedResponse, FollowingFeedSection, FollowingSort, FreeCreditsResponse, GetAchievementResponse, GetLeaderboardResponse, GoogleAppleLinkRequest, GoogleAppleLinkResponse, GoogleAppleSignInRequest, GoogleAppleSignInResponse, GoogleCreditPackFulfillmentRequest, GoogleOneTapExchangeRequest, GoogleOneTapExchangeResponse, GooglePendingSignupResponse, HomeCollectionPageResponse, HomeResponse, IapPurchaseRequest, IapPurchaseResponse, IapReceiptListParams, IapReceiptResponse, IapReceiptsResponse, InitializeAppUploadRequest, InitializeAppUploadResponse, InitializeAssetPackUploadRequest, InitializeAssetPackUploadResponse, InvitePreviewResponse, LibraryCategory, LibraryResponse, LibrarySort, LikedItemMutationResponse, ListAchievementsResponse, ListLeaderboardsResponse, ListOwnedCustomAssetsResponse, LoadOwnedCustomAssetResponse, LoginRequest, LoginResponse, LogoutResponse, MeAgentWorkersResponse, MeResponse, MobileCreditPackFulfillmentResponse, ModerationReportResponse, MutateOwnedCustomAssetRequest, MutateOwnedCustomAssetResponse, MyAchievementsResponse, MyAppsResponse, MyInviteCodeResponse, MyLeaderboardsResponse, NotificationReadResponse, NotificationStatus, NotificationsResponse, OwnedProfileAssetsResponse, PaymentProvider, PaymentStatus, PrivacyExportResponse, PublicEmailPreferencesResponse, PublicEmailPreferencesUpdateRequest, PurchaseResponse, PushSubscriptionMutationResponse, RecordAppUploadLaunchCheckRequest, RecordAppUploadLaunchCheckResponse, RecordAppUploadCausalCheckRequest, RecordAppUploadCausalCheckResponse, RecordAppUploadMediaCaptureRequest, RecordAppUploadMediaCaptureResponse, RegisterRequest, RegisterResponse, RemixScaffoldResponse, ResolveRuntimeAssetsRequest, ResolveRuntimeAssetsResponse, RetryAgentTaskResponse, ReviewState, SavedItemKind, SavedItemMutationResponse, SearchRequest, SearchResponse, SearchSuggestRequest, SearchSuggestResponse, SetAchievementProgressRequest, SetAchievementProgressResponse, SetProfileAssetRequest, SetProfileAssetResponse, ShopResponse, StarterProfileAssetsResponse, SubmitFeedbackRequest, SubmitFeedbackResponse, SubmitLeaderboardScoreRequest, SubmitLeaderboardScoreResponse, TagDetailResponse, TagDirectoryResponse, TagGroupDetailResponse, TagGroupSort, TagListResponse, TemplateScaffoldResponse, TrackEngagementEventRequest, TrackEngagementEventResponse, TractionAnalyticsResponse, TransactionsResponse, UnlinkGoogleResponse, UnlinkXResponse, UnlockAchievementResponse, UpdateAdminFeedbackRequest, UpdateAdminFeedbackResponse, UpdateAdminGameCollectionGamesRequest, UpdateAdminGameCollectionRequest, UpdateAdminUserRequest, UpdateAppRequest, UpdateAppResponse, UpdateAssetPackRequest, UpdateAssetPackResponse, UpdateAssetPackVersionRequest, UpdateAssetPackVersionResponse, UpdateAssetRequest, UpdateAssetResponse, UpdateAssetSpecVersionResponse, UpdateAssetVersionRequest, UpdateAssetVersionResponse, UpdateProfileRequest, UpdateProfileResponse, UpdatePreferredLocaleRequest, UpdatePreferredLocaleResponse, UpdateTagGroupRequest, UpdateTagRequest, UpdateUserCommunicationPreferencesRequest, UpdateVersionResponse, UploadAppSessionFileResponse, UploadAppSessionOwnedAssetResponse, UploadAssetPackSessionAssetResponse, UploadAssetPackSessionMediaResponse, UpsertWebPushSubscriptionRequest, UserDetailResponse, UsernameAvailableResponse, UsersListResponse, WebPushConfigResponse, WebPushSubscriptionStatusResponse, WorkerAgentTaskAttemptUnavailableRequest, WorkerAgentTaskAttemptUnavailableResponse, WorkerClaimAgentTaskRequest, WorkerClaimAgentTaskResponse, WorkerClaimAgentTaskSlugRequest, WorkerClaimAgentTaskSlugResponse, WorkerCompleteAgentTaskRequest, WorkerCompleteReleaseSmokeRequest, WorkerCreateAgentTaskEventRequest, WorkerCreateAgentTaskEventResponse, WorkerCreateAgentTaskTranscriptChunkRequest, WorkerCreateAgentTaskTranscriptChunkResponse, WorkerFailAgentTaskRequest, WorkerHeartbeatAgentTaskRequest, WorkerHeartbeatAgentTaskResponse, WorkerPresenceRequest, WorkerPresenceResponse, RegisterAgentBundleRequest, RegisterAgentBundleResponse, WorkerRecordAgentTaskRunTelemetryRequest, WorkerRecordAgentTaskRunTelemetryResponse, WorkerSubmitAgentTaskEvalRequest, WorkerSubmitAgentTaskEvalResponse, WorkerSubmitAgentTaskReviewRequest, WorkerSubmitAgentTaskReviewResponse, WorkerAgentTaskMaterialResponse, WorkerUpdateIntentRequest, WorkerUpdateIntentResponse, XPendingSignupResponse } from '@playdrop/types';
2
2
  import { type AdminAgentTaskTranscriptOptions, type CreationGamesFetchResult, type GetCreationConversationOptions, type ListAgentTasksOptions, type ListCreatorGamesOptions, type UploadWorkerAgentTaskMaterialOptions } from './domains/agent-tasks.js';
3
3
  export interface HttpMethod {
4
4
  GET: 'GET';
@@ -112,6 +112,7 @@ export interface ApiClient {
112
112
  logout(): Promise<LogoutResponse>;
113
113
  me(): Promise<MeResponse>;
114
114
  updateProfile(request: UpdateProfileRequest): Promise<UpdateProfileResponse>;
115
+ updatePreferredLocale(request: UpdatePreferredLocaleRequest): Promise<UpdatePreferredLocaleResponse>;
115
116
  changePassword(request: ChangePasswordRequest): Promise<ChangePasswordResponse>;
116
117
  exportPrivacyData(): Promise<PrivacyExportResponse>;
117
118
  deleteAccount(request: DeleteMyAccountRequest): Promise<DeleteMyAccountResponse>;
@@ -519,18 +520,12 @@ export interface ApiClient {
519
520
  deleteAppVersion(creatorUsername: string, appName: string, version: string): Promise<DeleteVersionResponse>;
520
521
  fetchPublicCreditShop(): Promise<ShopResponse>;
521
522
  fetchCreditShop(): Promise<ShopResponse>;
522
- createCreditPackCheckoutSession(sku: string, request?: CreditPackCheckoutSessionRequest): Promise<CreditPackCheckoutSessionResponse>;
523
+ createCreditPackCheckoutSession(sku: string, request: CreditPackCheckoutSessionRequest): Promise<CreditPackCheckoutSessionResponse>;
523
524
  fetchCreditPackCheckoutStatus(sessionId: string): Promise<CreditPackCheckoutStatusResponse>;
524
- createCreatorPlanCheckoutSession(tier: Exclude<CreatorPlanTier, 'BASIC'>, requestKey: string, request?: {
525
- nextPath?: string;
526
- }): Promise<CreatorPlanCheckoutSessionResponse>;
525
+ createCreatorPlanCheckoutSession(tier: Exclude<CreatorPlanTier, 'BASIC'>, requestKey: string, request: CreatorPlanSessionRequest): Promise<CreatorPlanCheckoutSessionResponse>;
527
526
  fetchCreatorPlanCheckoutStatus(sessionId: string): Promise<CreatorPlanCheckoutSessionStatusResponse>;
528
- createCreatorPlanChangeSession(tier: Exclude<CreatorPlanTier, 'BASIC'>, request?: {
529
- nextPath?: string;
530
- }): Promise<CreatorPlanPortalSessionResponse>;
531
- createCreatorPlanPortalSession(request?: {
532
- nextPath?: string;
533
- }): Promise<CreatorPlanPortalSessionResponse>;
527
+ createCreatorPlanChangeSession(tier: Exclude<CreatorPlanTier, 'BASIC'>, request: CreatorPlanSessionRequest): Promise<CreatorPlanPortalSessionResponse>;
528
+ createCreatorPlanPortalSession(request: CreatorPlanSessionRequest): Promise<CreatorPlanPortalSessionResponse>;
534
529
  reconcileCreatorPlanSubscription(): Promise<{
535
530
  creatorPlan: CreatorPlanState;
536
531
  }>;
@@ -574,7 +569,7 @@ export interface ApiClient {
574
569
  setSelectedProfileAsset(request: SetProfileAssetRequest): Promise<SetProfileAssetResponse>;
575
570
  fetchHome(options?: FetchHomeOptions): Promise<HomeResponse>;
576
571
  fetchHomeGamesCollectionPage(collectionId: string, options?: Pick<AppBrowseRequest, 'limit' | 'offset' | 'auth' | 'controller' | 'controllerCompatible' | 'surface'>): Promise<HomeCollectionPageResponse>;
577
- fetchUsers(): Promise<UsersListResponse>;
572
+ fetchUsers(options?: FetchAdminUsersOptions): Promise<UsersListResponse>;
578
573
  fetchAdminCreatorSubscriptions(): Promise<AdminCreatorSubscriptionsResponse>;
579
574
  createAdminCreatorPlanGrant(userId: number, request: CreateCreatorPlanGrantRequest): Promise<CreatorPlanGrantMutationResponse>;
580
575
  revokeAdminCreatorPlanGrant(userId: number, grantId: number): Promise<CreatorPlanGrantMutationResponse>;