@playdrop/playdrop-cli 0.12.40 → 0.12.42
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/config/client-meta.json +2 -2
- package/dist/apps/index.d.ts +1 -0
- package/dist/apps/index.js +1 -0
- package/dist/apps/loadCheck.d.ts +18 -1
- package/dist/apps/loadCheck.js +223 -1
- package/dist/apps/playtestContract.d.ts +2 -0
- package/dist/apps/playtestContract.js +77 -0
- package/dist/apps/upload.d.ts +1 -0
- package/dist/apps/upload.js +17 -0
- package/dist/commands/check.js +20 -2
- package/dist/commands/upload.js +9 -1
- package/dist/commands/worker/instrument-evidence.js +8 -1
- package/dist/commands/worker.js +1 -1
- package/node_modules/@playdrop/api-client/dist/client.d.ts +2 -1
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts +2 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.js +11 -0
- package/node_modules/@playdrop/config/client-meta.json +2 -2
- package/node_modules/@playdrop/types/dist/api.d.ts +25 -0
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/api.js +3 -0
- package/node_modules/@playdrop/types/dist/app-playtest-tape.d.ts +5 -0
- package/node_modules/@playdrop/types/dist/app-playtest-tape.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/app-playtest-tape.js +82 -0
- package/node_modules/@playdrop/types/dist/instrument-evidence.d.ts +1 -0
- package/node_modules/@playdrop/types/dist/instrument-evidence.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/instrument-evidence.js +7 -0
- package/node_modules/@playdrop/types/dist/version.d.ts +49 -1
- package/node_modules/@playdrop/types/dist/version.d.ts.map +1 -1
- package/package.json +1 -1
package/config/client-meta.json
CHANGED
package/dist/apps/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export type AppPipelineOptions = {
|
|
|
25
25
|
agentTaskId?: number;
|
|
26
26
|
playtestProof?: AgentTaskPlaytestProof;
|
|
27
27
|
mediaCaptureRequired?: boolean;
|
|
28
|
+
machineCausalGateRequired?: boolean;
|
|
28
29
|
captureSession?: TaskCaptureSession | null;
|
|
29
30
|
};
|
|
30
31
|
export declare function runAppPipeline(client: ApiClient, task: AppTask, options?: AppPipelineOptions): Promise<AppPipelineResult>;
|
package/dist/apps/index.js
CHANGED
|
@@ -66,6 +66,7 @@ async function runAppPipeline(client, task, options) {
|
|
|
66
66
|
agentTaskId: options?.agentTaskId,
|
|
67
67
|
playtestProof: options?.playtestProof,
|
|
68
68
|
mediaCaptureRequired: options?.mediaCaptureRequired,
|
|
69
|
+
machineCausalGateRequired: options?.machineCausalGateRequired,
|
|
69
70
|
captureSession: options?.captureSession,
|
|
70
71
|
};
|
|
71
72
|
const upload = await (0, upload_1.uploadApp)(client, task, artifacts, uploadOptions);
|
package/dist/apps/loadCheck.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ApiClient } from '@playdrop/api-client';
|
|
2
|
-
import { type AppPlaytestTape, type AppSurface, type UserResponse } from '@playdrop/types';
|
|
2
|
+
import { type AppPlaytestTape, type AppSurface, type AppUploadCausalComparison, type AppUploadMachineCausalEvidence, type UserResponse } from '@playdrop/types';
|
|
3
3
|
import type { BrowserContextOptions, Frame, Page } from 'playwright-core';
|
|
4
4
|
import type { AppTask } from '../catalogue';
|
|
5
5
|
import { type TaskCaptureSession } from '../appUrls';
|
|
@@ -84,4 +84,21 @@ export declare function runUploadedHostedLoadCheck(input: {
|
|
|
84
84
|
currentUser?: UserResponse | null;
|
|
85
85
|
captureSession?: TaskCaptureSession | null;
|
|
86
86
|
screenshotPath?: string | null;
|
|
87
|
+
readyGameFrameScreenshotPath?: string | null;
|
|
88
|
+
gameFrameScreenshotPath?: string | null;
|
|
89
|
+
playtestTape?: AppPlaytestTape;
|
|
90
|
+
postReadyWaitMs?: number;
|
|
87
91
|
}): Promise<HostedLoadCheckResult>;
|
|
92
|
+
export declare function sliceFirstPrimaryVerbAction(tape: AppPlaytestTape): AppPlaytestTape;
|
|
93
|
+
export declare function compareCausalFrames(firstPath: string, secondPath: string): Promise<AppUploadCausalComparison>;
|
|
94
|
+
export declare function runUploadedHostedCausalCheck(input: {
|
|
95
|
+
client: ApiClient;
|
|
96
|
+
creatorUsername: string;
|
|
97
|
+
task: AppTask;
|
|
98
|
+
sessionId: string;
|
|
99
|
+
teachingText: string;
|
|
100
|
+
timeoutMs?: number;
|
|
101
|
+
token?: string | null;
|
|
102
|
+
currentUser?: UserResponse | null;
|
|
103
|
+
captureSession?: TaskCaptureSession | null;
|
|
104
|
+
}): Promise<AppUploadMachineCausalEvidence>;
|
package/dist/apps/loadCheck.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.PLAYDROP_SURFACE_CONTEXT_OPTIONS = void 0;
|
|
4
7
|
exports.resolveLoadCheckSurface = resolveLoadCheckSurface;
|
|
@@ -12,9 +15,15 @@ exports.formatHostedLoadCheckFailure = formatHostedLoadCheckFailure;
|
|
|
12
15
|
exports.redactHostedLoadCheckSecrets = redactHostedLoadCheckSecrets;
|
|
13
16
|
exports.runLocalHostedLoadCheck = runLocalHostedLoadCheck;
|
|
14
17
|
exports.runUploadedHostedLoadCheck = runUploadedHostedLoadCheck;
|
|
18
|
+
exports.sliceFirstPrimaryVerbAction = sliceFirstPrimaryVerbAction;
|
|
19
|
+
exports.compareCausalFrames = compareCausalFrames;
|
|
20
|
+
exports.runUploadedHostedCausalCheck = runUploadedHostedCausalCheck;
|
|
15
21
|
const types_1 = require("@playdrop/types");
|
|
22
|
+
const node_crypto_1 = require("node:crypto");
|
|
16
23
|
const promises_1 = require("node:fs/promises");
|
|
24
|
+
const node_os_1 = require("node:os");
|
|
17
25
|
const node_path_1 = require("node:path");
|
|
26
|
+
const sharp_1 = __importDefault(require("sharp"));
|
|
18
27
|
const appUrls_1 = require("../appUrls");
|
|
19
28
|
const devShared_1 = require("../commands/devShared");
|
|
20
29
|
const dev_1 = require("../commands/dev");
|
|
@@ -30,6 +39,8 @@ Object.defineProperty(exports, "PLAYDROP_SURFACE_CONTEXT_OPTIONS", { enumerable:
|
|
|
30
39
|
const FRAME_SELECTOR = 'iframe[title="Game"]';
|
|
31
40
|
const DEFAULT_HOSTED_LOAD_TIMEOUT_MS = 15000;
|
|
32
41
|
const POST_READY_SETTLE_MS = 750;
|
|
42
|
+
const CAUSAL_FRAME_MEAN_DELTA_MIN = 0.025;
|
|
43
|
+
const CAUSAL_FRAME_CHANGED_PIXEL_RATIO_MIN = 0.12;
|
|
33
44
|
const LOAD_CHECK_SURFACE_ORDER = ['DESKTOP', 'MOBILE_LANDSCAPE', 'MOBILE_PORTRAIT'];
|
|
34
45
|
const GOOGLE_TELEMETRY_HOSTS = [
|
|
35
46
|
'analytics.google.com',
|
|
@@ -499,6 +510,14 @@ async function saveScreenshot(page, screenshotPath) {
|
|
|
499
510
|
console.log(`[check] Saved screenshot to ${(0, node_path_1.relative)(process.cwd(), normalizedPath) || normalizedPath}`);
|
|
500
511
|
return normalizedPath;
|
|
501
512
|
}
|
|
513
|
+
async function saveGameFrameScreenshot(page, screenshotPath) {
|
|
514
|
+
const normalizedPath = typeof screenshotPath === 'string' ? screenshotPath.trim() : '';
|
|
515
|
+
if (!normalizedPath)
|
|
516
|
+
return null;
|
|
517
|
+
await (0, promises_1.mkdir)((0, node_path_1.dirname)(normalizedPath), { recursive: true });
|
|
518
|
+
await page.locator(FRAME_SELECTOR).screenshot({ path: normalizedPath, type: 'png' });
|
|
519
|
+
return normalizedPath;
|
|
520
|
+
}
|
|
502
521
|
function normalizeLoadCheckFailure(error, artifactFingerprint) {
|
|
503
522
|
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
504
523
|
const message = normalizeLoadCheckMessage(rawMessage);
|
|
@@ -716,7 +735,7 @@ async function runHostedLoadCheck(options) {
|
|
|
716
735
|
hostedLaunchWaiter,
|
|
717
736
|
page.waitForTimeout(timeoutMs).then(() => {
|
|
718
737
|
throw new Error(expectedHostedLaunchState === 'ready'
|
|
719
|
-
? 'hosted_app_missing_ready: Hosted app did not report ready before the
|
|
738
|
+
? 'hosted_app_missing_ready: instrument_error:game_ready_timeout: Hosted app did not report sdk.host.ready() before the instrument timeout.'
|
|
720
739
|
: `hosted_app_gate_missing: Hosted app did not report ${expectedHostedLaunchState} before the load-check timeout.`);
|
|
721
740
|
}),
|
|
722
741
|
]);
|
|
@@ -737,6 +756,7 @@ async function runHostedLoadCheck(options) {
|
|
|
737
756
|
if (isSoftwareWebGlRenderer(webglRenderer)) {
|
|
738
757
|
throw new Error(`project_check_webgl_renderer_software: WebGL renderer is "${webglRenderer}". Real hardware acceleration is required.`);
|
|
739
758
|
}
|
|
759
|
+
await saveGameFrameScreenshot(page, options.readyGameFrameScreenshotPath);
|
|
740
760
|
if (options.playtestTape && options.actions?.length) {
|
|
741
761
|
throw new Error('project_check_input_mode_conflict: playtest tape and legacy actions cannot run together.');
|
|
742
762
|
}
|
|
@@ -753,6 +773,7 @@ async function runHostedLoadCheck(options) {
|
|
|
753
773
|
else if (options.postReadyWaitMs && options.postReadyWaitMs > 0) {
|
|
754
774
|
await page.waitForTimeout(options.postReadyWaitMs);
|
|
755
775
|
}
|
|
776
|
+
await saveGameFrameScreenshot(page, options.gameFrameScreenshotPath);
|
|
756
777
|
screenshotPath = await saveScreenshot(page, options.screenshotPath);
|
|
757
778
|
}, {
|
|
758
779
|
...options.contextOptions,
|
|
@@ -981,6 +1002,11 @@ async function runUploadedHostedLoadCheck(input) {
|
|
|
981
1002
|
expectedHostedLaunchState: resolvePostAuthHostedLaunchState(preview.localAppMetadata.controllerMode),
|
|
982
1003
|
contextOptions,
|
|
983
1004
|
screenshotPath: input.screenshotPath,
|
|
1005
|
+
readyGameFrameScreenshotPath: input.readyGameFrameScreenshotPath,
|
|
1006
|
+
gameFrameScreenshotPath: input.gameFrameScreenshotPath,
|
|
1007
|
+
playtestTape: input.playtestTape,
|
|
1008
|
+
playtestSurface: captureSurface,
|
|
1009
|
+
postReadyWaitMs: input.postReadyWaitMs,
|
|
984
1010
|
});
|
|
985
1011
|
}
|
|
986
1012
|
else if (anonymousExpectedState === 'login_required') {
|
|
@@ -1009,6 +1035,11 @@ async function runUploadedHostedLoadCheck(input) {
|
|
|
1009
1035
|
savedSessionBootstrap: true,
|
|
1010
1036
|
contextOptions,
|
|
1011
1037
|
screenshotPath: input.screenshotPath,
|
|
1038
|
+
readyGameFrameScreenshotPath: input.readyGameFrameScreenshotPath,
|
|
1039
|
+
gameFrameScreenshotPath: input.gameFrameScreenshotPath,
|
|
1040
|
+
playtestTape: input.playtestTape,
|
|
1041
|
+
playtestSurface: captureSurface,
|
|
1042
|
+
postReadyWaitMs: input.postReadyWaitMs,
|
|
1012
1043
|
});
|
|
1013
1044
|
}
|
|
1014
1045
|
}
|
|
@@ -1021,6 +1052,11 @@ async function runUploadedHostedLoadCheck(input) {
|
|
|
1021
1052
|
expectedHostedLaunchState: anonymousExpectedState,
|
|
1022
1053
|
contextOptions,
|
|
1023
1054
|
screenshotPath: input.screenshotPath,
|
|
1055
|
+
readyGameFrameScreenshotPath: input.readyGameFrameScreenshotPath,
|
|
1056
|
+
gameFrameScreenshotPath: input.gameFrameScreenshotPath,
|
|
1057
|
+
playtestTape: input.playtestTape,
|
|
1058
|
+
playtestSurface: captureSurface,
|
|
1059
|
+
postReadyWaitMs: input.postReadyWaitMs,
|
|
1024
1060
|
});
|
|
1025
1061
|
}
|
|
1026
1062
|
const recorded = await input.client.recordAppUploadLaunchCheck(input.creatorUsername, input.task.name, input.sessionId, {
|
|
@@ -1042,3 +1078,189 @@ async function runUploadedHostedLoadCheck(input) {
|
|
|
1042
1078
|
artifactFingerprint: recordedLaunchCheck.artifactFingerprint,
|
|
1043
1079
|
};
|
|
1044
1080
|
}
|
|
1081
|
+
function sliceFirstPrimaryVerbAction(tape) {
|
|
1082
|
+
const prefix = tape.events.slice(0, tape.startOnlyEventCount);
|
|
1083
|
+
const postStartEvents = tape.events.slice(tape.startOnlyEventCount);
|
|
1084
|
+
let actionEventCount = 0;
|
|
1085
|
+
if (tape.primaryVerb === 'tap') {
|
|
1086
|
+
actionEventCount = 1;
|
|
1087
|
+
}
|
|
1088
|
+
else if (tape.primaryVerb === 'key') {
|
|
1089
|
+
const activeKeys = new Set();
|
|
1090
|
+
for (let index = 0; index < postStartEvents.length; index += 1) {
|
|
1091
|
+
const event = postStartEvents[index];
|
|
1092
|
+
if (event.type === 'keyDown')
|
|
1093
|
+
activeKeys.add(event.key);
|
|
1094
|
+
if (event.type === 'keyUp')
|
|
1095
|
+
activeKeys.delete(event.key);
|
|
1096
|
+
if (activeKeys.size === 0 && index > 0) {
|
|
1097
|
+
actionEventCount = index + 1;
|
|
1098
|
+
break;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
const activePointers = new Set();
|
|
1104
|
+
for (let index = 0; index < postStartEvents.length; index += 1) {
|
|
1105
|
+
const event = postStartEvents[index];
|
|
1106
|
+
if (event.type === 'pointerDown')
|
|
1107
|
+
activePointers.add(event.pointerId ?? 0);
|
|
1108
|
+
if (event.type === 'pointerUp')
|
|
1109
|
+
activePointers.delete(event.pointerId ?? 0);
|
|
1110
|
+
if (activePointers.size === 0 && index > 0) {
|
|
1111
|
+
actionEventCount = index + 1;
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
if (actionEventCount <= 0) {
|
|
1117
|
+
throw new Error(`agent_task_machine_causal_gate_invalid_tape:first_${tape.primaryVerb}_action_incomplete`);
|
|
1118
|
+
}
|
|
1119
|
+
return {
|
|
1120
|
+
...tape,
|
|
1121
|
+
events: [...prefix, ...postStartEvents.slice(0, actionEventCount)],
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
async function hashFile(path) {
|
|
1125
|
+
return (0, node_crypto_1.createHash)('sha256').update(await (0, promises_1.readFile)(path)).digest('hex');
|
|
1126
|
+
}
|
|
1127
|
+
async function compareCausalFrames(firstPath, secondPath) {
|
|
1128
|
+
const readPixels = async (path) => {
|
|
1129
|
+
return await (0, sharp_1.default)(path)
|
|
1130
|
+
.resize(64, 64, { fit: 'fill' })
|
|
1131
|
+
.greyscale()
|
|
1132
|
+
.raw()
|
|
1133
|
+
.toBuffer();
|
|
1134
|
+
};
|
|
1135
|
+
const [first, second] = await Promise.all([readPixels(firstPath), readPixels(secondPath)]);
|
|
1136
|
+
if (first.length !== second.length || first.length === 0) {
|
|
1137
|
+
throw new Error('agent_task_machine_causal_gate_frame_shape_mismatch');
|
|
1138
|
+
}
|
|
1139
|
+
let deltaTotal = 0;
|
|
1140
|
+
let changedPixels = 0;
|
|
1141
|
+
for (let index = 0; index < first.length; index += 1) {
|
|
1142
|
+
const delta = Math.abs(first[index] - second[index]);
|
|
1143
|
+
deltaTotal += delta;
|
|
1144
|
+
if (delta >= 16)
|
|
1145
|
+
changedPixels += 1;
|
|
1146
|
+
}
|
|
1147
|
+
const meanDelta = deltaTotal / first.length / 255;
|
|
1148
|
+
const changedPixelRatio = changedPixels / first.length;
|
|
1149
|
+
return {
|
|
1150
|
+
meanDelta,
|
|
1151
|
+
changedPixelRatio,
|
|
1152
|
+
passed: meanDelta >= CAUSAL_FRAME_MEAN_DELTA_MIN || changedPixelRatio >= CAUSAL_FRAME_CHANGED_PIXEL_RATIO_MIN,
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
async function runUploadedHostedCausalCheck(input) {
|
|
1156
|
+
const primarySurface = input.task.primarySurface;
|
|
1157
|
+
const fullTape = primarySurface ? input.task.playtestTapes?.[primarySurface] : null;
|
|
1158
|
+
if (!primarySurface || !fullTape) {
|
|
1159
|
+
throw new Error('agent_task_machine_causal_gate_primary_tape_required');
|
|
1160
|
+
}
|
|
1161
|
+
if (fullTape.startOnlyEventCount <= 0) {
|
|
1162
|
+
throw new Error('agent_task_machine_causal_gate_start_only_required');
|
|
1163
|
+
}
|
|
1164
|
+
const startOnlyTape = {
|
|
1165
|
+
...fullTape,
|
|
1166
|
+
events: fullTape.events.slice(0, fullTape.startOnlyEventCount),
|
|
1167
|
+
};
|
|
1168
|
+
const firstActionTape = sliceFirstPrimaryVerbAction(fullTape);
|
|
1169
|
+
const tempDir = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'playdrop-causal-gate-'));
|
|
1170
|
+
const paths = {
|
|
1171
|
+
zeroInput: (0, node_path_1.join)(tempDir, 'zero-input.png'),
|
|
1172
|
+
startOnlyReady: (0, node_path_1.join)(tempDir, 'start-only-ready.png'),
|
|
1173
|
+
startOnly: (0, node_path_1.join)(tempDir, 'start-only.png'),
|
|
1174
|
+
firstAction: (0, node_path_1.join)(tempDir, 'first-action.png'),
|
|
1175
|
+
fullTape: (0, node_path_1.join)(tempDir, 'full-tape.png'),
|
|
1176
|
+
};
|
|
1177
|
+
const run = async (label, options) => {
|
|
1178
|
+
console.log(`[upload] Machine causal gate: ${label} from sdk.host.ready().`);
|
|
1179
|
+
const result = await runUploadedHostedLoadCheck({
|
|
1180
|
+
client: input.client,
|
|
1181
|
+
creatorUsername: input.creatorUsername,
|
|
1182
|
+
task: input.task,
|
|
1183
|
+
sessionId: input.sessionId,
|
|
1184
|
+
timeoutMs: input.timeoutMs,
|
|
1185
|
+
token: input.token,
|
|
1186
|
+
currentUser: input.currentUser,
|
|
1187
|
+
captureSession: input.captureSession,
|
|
1188
|
+
...options,
|
|
1189
|
+
});
|
|
1190
|
+
if (result.status !== 'PASSED') {
|
|
1191
|
+
throw new Error(`Machine causal ${label} run failed. ${formatHostedLoadCheckFailure(input.task.name, result, 'staged')}`);
|
|
1192
|
+
}
|
|
1193
|
+
if (!result.artifactFingerprint) {
|
|
1194
|
+
throw new Error('agent_task_machine_causal_gate_artifact_fingerprint_missing');
|
|
1195
|
+
}
|
|
1196
|
+
return result;
|
|
1197
|
+
};
|
|
1198
|
+
try {
|
|
1199
|
+
const zeroInput = await run('zero-input', {
|
|
1200
|
+
postReadyWaitMs: fullTape.durationMs,
|
|
1201
|
+
gameFrameScreenshotPath: paths.zeroInput,
|
|
1202
|
+
});
|
|
1203
|
+
const startOnly = await run('start-only', {
|
|
1204
|
+
playtestTape: startOnlyTape,
|
|
1205
|
+
readyGameFrameScreenshotPath: paths.startOnlyReady,
|
|
1206
|
+
gameFrameScreenshotPath: paths.startOnly,
|
|
1207
|
+
});
|
|
1208
|
+
const firstAction = await run('first-action', {
|
|
1209
|
+
playtestTape: firstActionTape,
|
|
1210
|
+
gameFrameScreenshotPath: paths.firstAction,
|
|
1211
|
+
});
|
|
1212
|
+
const full = await run('full-tape', {
|
|
1213
|
+
playtestTape: fullTape,
|
|
1214
|
+
gameFrameScreenshotPath: paths.fullTape,
|
|
1215
|
+
});
|
|
1216
|
+
const artifactFingerprint = full.artifactFingerprint;
|
|
1217
|
+
if ([zeroInput, startOnly, firstAction].some((result) => result.artifactFingerprint !== artifactFingerprint)) {
|
|
1218
|
+
throw new Error('agent_task_machine_causal_gate_artifact_changed_during_check');
|
|
1219
|
+
}
|
|
1220
|
+
const comparisons = {
|
|
1221
|
+
startOnlyVsReady: await compareCausalFrames(paths.startOnlyReady, paths.startOnly),
|
|
1222
|
+
startOnlyVsZeroInput: await compareCausalFrames(paths.zeroInput, paths.startOnly),
|
|
1223
|
+
fullTapeVsZeroInput: await compareCausalFrames(paths.zeroInput, paths.fullTape),
|
|
1224
|
+
fullTapeVsStartOnly: await compareCausalFrames(paths.startOnly, paths.fullTape),
|
|
1225
|
+
fullTapeVsFirstAction: await compareCausalFrames(paths.firstAction, paths.fullTape),
|
|
1226
|
+
};
|
|
1227
|
+
if (!comparisons.startOnlyVsReady.passed || !comparisons.startOnlyVsZeroInput.passed) {
|
|
1228
|
+
throw new Error('agent_task_machine_causal_gate_failed:start-only did not provably leave the title state. Fix the start action or ready-relative timing.');
|
|
1229
|
+
}
|
|
1230
|
+
if (!comparisons.fullTapeVsZeroInput.passed || !comparisons.fullTapeVsStartOnly.passed) {
|
|
1231
|
+
throw new Error('agent_task_machine_causal_gate_failed:full tape did not meaningfully beat zero-input and start-only controls. Fix the game or tape before upload.');
|
|
1232
|
+
}
|
|
1233
|
+
if (!comparisons.fullTapeVsFirstAction.passed) {
|
|
1234
|
+
throw new Error('agent_task_machine_causal_gate_failed:first primary action trivially reached the full-tape outcome. Add a sustained causal loop before upload.');
|
|
1235
|
+
}
|
|
1236
|
+
const teachingText = input.teachingText.trim();
|
|
1237
|
+
const evidence = {
|
|
1238
|
+
version: 1,
|
|
1239
|
+
source: 'CLI_MACHINE',
|
|
1240
|
+
artifactFingerprint,
|
|
1241
|
+
primarySurface,
|
|
1242
|
+
primaryVerb: fullTape.primaryVerb,
|
|
1243
|
+
runs: {
|
|
1244
|
+
zeroInput: { finalFrameSha256: await hashFile(paths.zeroInput) },
|
|
1245
|
+
startOnly: {
|
|
1246
|
+
readyFrameSha256: await hashFile(paths.startOnlyReady),
|
|
1247
|
+
finalFrameSha256: await hashFile(paths.startOnly),
|
|
1248
|
+
},
|
|
1249
|
+
firstAction: { finalFrameSha256: await hashFile(paths.firstAction) },
|
|
1250
|
+
fullTape: { finalFrameSha256: await hashFile(paths.fullTape) },
|
|
1251
|
+
},
|
|
1252
|
+
comparisons,
|
|
1253
|
+
teachingText,
|
|
1254
|
+
teachingTextSha256: (0, node_crypto_1.createHash)('sha256').update(teachingText).digest('hex'),
|
|
1255
|
+
};
|
|
1256
|
+
const recorded = await input.client.recordAppUploadCausalCheck(input.creatorUsername, input.task.name, input.sessionId, { evidence });
|
|
1257
|
+
if (recorded.session.causalCheck.status !== 'PASSED') {
|
|
1258
|
+
throw new Error('agent_task_machine_causal_gate_not_recorded');
|
|
1259
|
+
}
|
|
1260
|
+
console.log(`[upload] Machine causal gate passed for ${input.creatorUsername}/${input.task.name}.`);
|
|
1261
|
+
return evidence;
|
|
1262
|
+
}
|
|
1263
|
+
finally {
|
|
1264
|
+
await (0, promises_1.rm)(tempDir, { recursive: true, force: true });
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertPrimaryVerbTeachingParity = assertPrimaryVerbTeachingParity;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const types_1 = require("@playdrop/types");
|
|
7
|
+
function extractPotentialPlayerText(source, extension) {
|
|
8
|
+
const candidates = new Set();
|
|
9
|
+
if (extension === '.html') {
|
|
10
|
+
const visibleText = source
|
|
11
|
+
.replace(/<!--[\s\S]*?-->/g, ' ')
|
|
12
|
+
.replace(/<(?:script|style)\b[^>]*>[\s\S]*?<\/(?:script|style)>/gi, ' ')
|
|
13
|
+
.replace(/<[^>]+>/g, ' ')
|
|
14
|
+
.replace(/\s+/g, ' ')
|
|
15
|
+
.trim();
|
|
16
|
+
if (visibleText)
|
|
17
|
+
candidates.add(visibleText.slice(0, 300));
|
|
18
|
+
}
|
|
19
|
+
const stringLiteral = /"((?:\\.|[^"\\]){1,300})"|'((?:\\.|[^'\\]){1,300})'|`((?:\\.|[^`\\]){1,300})`/g;
|
|
20
|
+
for (const match of source.matchAll(stringLiteral)) {
|
|
21
|
+
const text = (match[1] ?? match[2] ?? match[3] ?? '')
|
|
22
|
+
.replace(/\\[nrt]/g, ' ')
|
|
23
|
+
.replace(/\s+/g, ' ')
|
|
24
|
+
.trim();
|
|
25
|
+
if (text)
|
|
26
|
+
candidates.add(text);
|
|
27
|
+
}
|
|
28
|
+
return Array.from(candidates);
|
|
29
|
+
}
|
|
30
|
+
function readPrimaryVerbTeachingText(task) {
|
|
31
|
+
const runtimeRoot = (0, node_path_1.dirname)(task.filePath);
|
|
32
|
+
const matches = new Set();
|
|
33
|
+
const walk = (dir) => {
|
|
34
|
+
for (const entry of (0, node_fs_1.readdirSync)(dir, { withFileTypes: true })) {
|
|
35
|
+
const absolute = (0, node_path_1.join)(dir, entry.name);
|
|
36
|
+
if (entry.isDirectory()) {
|
|
37
|
+
if (!['node_modules', '.git', 'assets'].includes(entry.name))
|
|
38
|
+
walk(absolute);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (!entry.isFile() || !['.html', '.js', '.mjs', '.cjs'].includes((0, node_path_1.extname)(entry.name).toLowerCase()))
|
|
42
|
+
continue;
|
|
43
|
+
const extension = (0, node_path_1.extname)(entry.name).toLowerCase();
|
|
44
|
+
const source = (0, node_fs_1.readFileSync)(absolute, 'utf8');
|
|
45
|
+
for (const text of extractPotentialPlayerText(source, extension)) {
|
|
46
|
+
if (types_1.APP_PLAYTEST_PRIMARY_VERB_VALUES.some((verb) => (0, types_1.appPlaytestTeachingTextMatchesVerb)(text, verb))) {
|
|
47
|
+
matches.add(text);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
walk(runtimeRoot);
|
|
53
|
+
return Array.from(matches);
|
|
54
|
+
}
|
|
55
|
+
function assertPrimaryVerbTeachingParity(task) {
|
|
56
|
+
const primarySurface = task.primarySurface;
|
|
57
|
+
const tape = primarySurface ? task.playtestTapes?.[primarySurface] : null;
|
|
58
|
+
if (!primarySurface || !tape) {
|
|
59
|
+
throw new Error('agent_task_primary_verb_tape_required');
|
|
60
|
+
}
|
|
61
|
+
const teachingTexts = readPrimaryVerbTeachingText(task);
|
|
62
|
+
const matchingText = teachingTexts.find((text) => (0, types_1.appPlaytestTeachingTextMatchesVerb)(text, tape.primaryVerb));
|
|
63
|
+
if (!matchingText) {
|
|
64
|
+
throw new Error(`agent_task_primary_verb_not_taught:${tape.primaryVerb}: show the player a concise instruction using the declared primary verb.`);
|
|
65
|
+
}
|
|
66
|
+
const competingVerbs = types_1.APP_PLAYTEST_PRIMARY_VERB_VALUES
|
|
67
|
+
.filter((verb) => verb !== tape.primaryVerb)
|
|
68
|
+
.filter((verb) => teachingTexts.some((text) => {
|
|
69
|
+
if (!(0, types_1.appPlaytestTeachingTextMatchesVerb)(text, verb))
|
|
70
|
+
return false;
|
|
71
|
+
return verb !== 'tap' || !/\btap\b[^\n]{0,30}\b(?:start|play|begin|continue|retry)\b/i.test(text);
|
|
72
|
+
}));
|
|
73
|
+
if (competingVerbs.length > 0) {
|
|
74
|
+
throw new Error(`agent_task_primary_verb_teaching_mismatch:${tape.primaryVerb}:${competingVerbs.join(',')}`);
|
|
75
|
+
}
|
|
76
|
+
return matchingText;
|
|
77
|
+
}
|
package/dist/apps/upload.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type AppUploadOptions = {
|
|
|
23
23
|
agentTaskId?: number;
|
|
24
24
|
playtestProof?: AgentTaskPlaytestProof;
|
|
25
25
|
mediaCaptureRequired?: boolean;
|
|
26
|
+
machineCausalGateRequired?: boolean;
|
|
26
27
|
captureSession?: TaskCaptureSession | null;
|
|
27
28
|
};
|
|
28
29
|
export declare function uploadApp(client: ApiClient, task: AppTask, artifacts: AppBuildArtifacts | null, options?: AppUploadOptions): Promise<AppUploadResult>;
|
package/dist/apps/upload.js
CHANGED
|
@@ -9,6 +9,7 @@ const node_path_1 = require("node:path");
|
|
|
9
9
|
const http_1 = require("../http");
|
|
10
10
|
const loadCheck_1 = require("./loadCheck");
|
|
11
11
|
const listingPreflight_1 = require("../listingPreflight");
|
|
12
|
+
const playtestContract_1 = require("./playtestContract");
|
|
12
13
|
const EXTENSION_TO_MIME = {
|
|
13
14
|
'.png': 'image/png',
|
|
14
15
|
'.jpg': 'image/jpeg',
|
|
@@ -353,6 +354,22 @@ async function uploadAppVersion(client, task, artifacts, options) {
|
|
|
353
354
|
await client.recordAppUploadMediaCapture(creatorUsername, task.name, sessionId, mediaCaptureProof);
|
|
354
355
|
}
|
|
355
356
|
if (task.hostingMode !== 'EXTERNAL'
|
|
357
|
+
&& !task.externalUrl
|
|
358
|
+
&& options?.machineCausalGateRequired) {
|
|
359
|
+
const teachingText = (0, playtestContract_1.assertPrimaryVerbTeachingParity)(task);
|
|
360
|
+
await (0, loadCheck_1.runUploadedHostedCausalCheck)({
|
|
361
|
+
client,
|
|
362
|
+
creatorUsername,
|
|
363
|
+
task,
|
|
364
|
+
sessionId,
|
|
365
|
+
teachingText,
|
|
366
|
+
timeoutMs: options.loadCheckTimeoutMs,
|
|
367
|
+
token: options?.token ?? null,
|
|
368
|
+
currentUser: options?.user ?? null,
|
|
369
|
+
captureSession: options?.captureSession,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
else if (task.hostingMode !== 'EXTERNAL'
|
|
356
373
|
&& !task.externalUrl
|
|
357
374
|
&& options?.runStagedUploadLoadCheck) {
|
|
358
375
|
const loadCheck = await (0, loadCheck_1.runUploadedHostedLoadCheck)({
|
package/dist/commands/check.js
CHANGED
|
@@ -222,6 +222,7 @@ async function check(targetArg, options = {}) {
|
|
|
222
222
|
});
|
|
223
223
|
if (tapeSurface && playtestTape) {
|
|
224
224
|
const idleScreenshotPath = buildComparisonScreenshotPath(screenshotPath, 'idle');
|
|
225
|
+
const startOnlyScreenshotPath = buildComparisonScreenshotPath(screenshotPath, 'start-only');
|
|
225
226
|
const tapeScreenshotPath = buildComparisonScreenshotPath(screenshotPath, 'tape');
|
|
226
227
|
console.log(`[check] Running ${playtestTape.durationMs} ms zero-input baseline on ${tapeSurface}.`);
|
|
227
228
|
const idleResult = await runCheck({
|
|
@@ -234,6 +235,22 @@ async function check(targetArg, options = {}) {
|
|
|
234
235
|
process.exitCode = 1;
|
|
235
236
|
return;
|
|
236
237
|
}
|
|
238
|
+
console.log(`[check] Reopening a clean run and executing only the first ${playtestTape.startOnlyEventCount} startup event(s).`);
|
|
239
|
+
const startOnlyTape = playtestTape.startOnlyEventCount > 0
|
|
240
|
+
? { ...playtestTape, events: playtestTape.events.slice(0, playtestTape.startOnlyEventCount) }
|
|
241
|
+
: null;
|
|
242
|
+
const startOnlyResult = await runCheck({
|
|
243
|
+
screenshotPath: startOnlyScreenshotPath,
|
|
244
|
+
surface: tapeSurface,
|
|
245
|
+
...(startOnlyTape
|
|
246
|
+
? { tape: startOnlyTape }
|
|
247
|
+
: { postReadyWaitMs: playtestTape.durationMs }),
|
|
248
|
+
});
|
|
249
|
+
if (startOnlyResult.status !== 'PASSED') {
|
|
250
|
+
(0, messages_1.printErrorWithHelp)((0, loadCheck_1.formatHostedLoadCheckFailure)(appName, startOnlyResult, 'local'), startOnlyResult.screenshotPath ? [`Start-only screenshot: ${startOnlyResult.screenshotPath}`] : [], { command: 'project check' });
|
|
251
|
+
process.exitCode = 1;
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
237
254
|
console.log(`[check] Reopening a clean run and executing the ${tapeSurface} tape.`);
|
|
238
255
|
const tapeResult = await runCheck({
|
|
239
256
|
screenshotPath: tapeScreenshotPath,
|
|
@@ -245,10 +262,11 @@ async function check(targetArg, options = {}) {
|
|
|
245
262
|
process.exitCode = 1;
|
|
246
263
|
return;
|
|
247
264
|
}
|
|
248
|
-
console.log(`[check] Captured matched idle and tape runs for ${currentUsername}/${appName}.`);
|
|
265
|
+
console.log(`[check] Captured matched idle, start-only, and tape runs for ${currentUsername}/${appName}.`);
|
|
249
266
|
console.log(`[check] Idle: ${idleResult.screenshotPath ?? idleScreenshotPath}`);
|
|
267
|
+
console.log(`[check] Start-only: ${startOnlyResult.screenshotPath ?? startOnlyScreenshotPath}`);
|
|
250
268
|
console.log(`[check] Tape: ${tapeResult.screenshotPath ?? tapeScreenshotPath}`);
|
|
251
|
-
console.log('[check] The tape passes only when visible evidence shows it meaningfully beats
|
|
269
|
+
console.log('[check] The tape passes only when visible evidence shows it meaningfully beats both controls.');
|
|
252
270
|
for (const signal of playtestTape.successSignals) {
|
|
253
271
|
console.log(`[check] Success signal ${signal.kind}: ${signal.description}`);
|
|
254
272
|
}
|
package/dist/commands/upload.js
CHANGED
|
@@ -1234,9 +1234,16 @@ function assertAgentNewGamePlaytestContract(task) {
|
|
|
1234
1234
|
throw new Error('agent_task_playtest_tapes_required: NEW_GAME catalogue.json must declare one playtest tape per supported surface.');
|
|
1235
1235
|
}
|
|
1236
1236
|
for (const surface of task.surfaceTargets) {
|
|
1237
|
-
|
|
1237
|
+
const tape = task.playtestTapes[surface];
|
|
1238
|
+
if (!tape) {
|
|
1238
1239
|
throw new Error(`agent_task_playtest_tape_missing:${surface}`);
|
|
1239
1240
|
}
|
|
1241
|
+
if (tape.startOnlyEventCount <= 0) {
|
|
1242
|
+
throw new Error(`agent_task_playtest_start_only_required:${surface}: the tape must include an explicit startup action.`);
|
|
1243
|
+
}
|
|
1244
|
+
if (tape.events[0]?.atMs !== 0) {
|
|
1245
|
+
throw new Error(`agent_task_playtest_ready_relative_timing_required:${surface}: the first startup event must run at 0 ms after sdk.host.ready().`);
|
|
1246
|
+
}
|
|
1240
1247
|
}
|
|
1241
1248
|
}
|
|
1242
1249
|
const WORKER_SUPERVISOR_SOURCE_EXCLUDES = [
|
|
@@ -2025,6 +2032,7 @@ async function publishWorkerAppProject(input) {
|
|
|
2025
2032
|
agentTaskId: input.taskId,
|
|
2026
2033
|
playtestProof: playtestProof ?? undefined,
|
|
2027
2034
|
mediaCaptureRequired: input.executionTarget === 'FIRST_PARTY',
|
|
2035
|
+
machineCausalGateRequired: input.kind === 'NEW_GAME',
|
|
2028
2036
|
captureSession,
|
|
2029
2037
|
});
|
|
2030
2038
|
if (!uploadResult.versionCreated || !uploadResult.version) {
|
|
@@ -257,7 +257,14 @@ function readAndValidateInstrumentEvidenceManifest(input) {
|
|
|
257
257
|
const captures = {};
|
|
258
258
|
const screenshotIds = new Set();
|
|
259
259
|
for (const name of types_1.INSTRUMENT_EVIDENCE_NAMES) {
|
|
260
|
-
const
|
|
260
|
+
const rawCapture = parsed.captures?.[name];
|
|
261
|
+
if (!rawCapture) {
|
|
262
|
+
if (types_1.REQUIRED_INSTRUMENT_EVIDENCE_NAMES.includes(name)) {
|
|
263
|
+
throw new Error(`invalid_instrument_evidence_capture:${name}`);
|
|
264
|
+
}
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
const capture = normalizeCapture(rawCapture, name);
|
|
261
268
|
if (capture.tabId !== controlledTabId) {
|
|
262
269
|
throw new Error(`instrument_evidence_tab_mismatch:${controlledTabId}:${capture.tabId}`);
|
|
263
270
|
}
|
package/dist/commands/worker.js
CHANGED
|
@@ -5048,7 +5048,7 @@ async function submitEvalTask(options) {
|
|
|
5048
5048
|
for (const name of ['first-frame', 'core', 'win', 'loss']) {
|
|
5049
5049
|
const capture = manifest.captures[name];
|
|
5050
5050
|
if (!capture) {
|
|
5051
|
-
|
|
5051
|
+
continue;
|
|
5052
5052
|
}
|
|
5053
5053
|
const filePath = node_path_1.default.join(node_path_1.default.resolve(evidenceDir), capture.fileName);
|
|
5054
5054
|
evidenceFiles.push({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AbortAppUploadResponse, AbortAssetPackUploadResponse, AdInterstitialShowResponse, AdLoadRequest, AdLoadResponse, AdRewardedShowResponse, AdShowRequest, AdminAgentTaskDetailResponse, AdminAgentTaskTranscriptResponse, AdminAgentTasksResponse, AdminAgentWorkersStatusResponse, AdminAppPlayerMetaResponse, AdminAppPlayerMetaUserResponse, AdminAppVersionReviewsListResponse, AdminAppsListResponse, AdminCreatorEngagementExecutionsResponse, AdminCreatorEngagementRulePreviewRequest, AdminCreatorEngagementRulePreviewResponse, AdminCreatorEngagementRulesResponse, AdminCreatorEngagementUserResponse, AdminCreditTransactionsResponse, AdminEnqueueNextAppVersionReviewTaskResponse, AdminFeedbackListResponse, AdminFeedbackResponse, AdminGameCollectionCandidatesResponse, AdminGameCollectionResponse, AdminGameCollectionsResponse, AdminMutateAchievementStateRequest, AdminMutateAchievementStateResponse, AdminMutateLeaderboardScoreRequest, AdminMutateLeaderboardScoreResponse, AdminPaymentDetailResponse, AdminPaymentsListResponse, AdminPlatformAnalyticsRequest, AdminPlatformAnalyticsResponse, 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, AppMoreCollectionKey, AppMoreCollectionPage, AppMoreCollectionRequest, AppMoreCollectionsRequest, AppMoreCollectionsResponse, AppRuntimeAssetsResponse, AppSourceBundleResponse, AppType, AppUploadLaunchCheckPreviewResponse, AppVersionDetailResponse, AppVersionVisibility, 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, CreateRemixGameAgentTaskRequest, CreateRemixGameAgentTaskResponse, CreateTagGroupRequest, CreateTagRequest, CreateUserRequest, CreateUserResponse, CreatorAppsBrowseRequest, CreatorBlockMutationResponse, CreatorEarningsResponse, CreatorEngagementRuleExecutionStatus, CreatorFollowMutationResponse, CreatorGameCreatorFeedbackStatusResponse, CreatorGameShareResponse, CreatorGameStatusResponse, CreatorGameVersionsResponse, CreatorGamesListResponse, CreditPackCheckoutSessionRequest, CreditPackCheckoutSessionResponse, CreditPackCheckoutStatusResponse, 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, FinalizeAssetPackUploadResponse, FirebasePushDeviceRequest, FirebasePushDeviceStatusResponse, 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, 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, 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, WorkerCreateAgentTaskEventRequest, WorkerCreateAgentTaskEventResponse, WorkerCreateAgentTaskTranscriptChunkRequest, WorkerCreateAgentTaskTranscriptChunkResponse, WorkerFailAgentTaskRequest, WorkerHeartbeatAgentTaskRequest, WorkerHeartbeatAgentTaskResponse, WorkerPresenceRequest, WorkerPresenceResponse, RegisterAgentBundleRequest, RegisterAgentBundleResponse, WorkerRecordAgentTaskRunTelemetryRequest, WorkerRecordAgentTaskRunTelemetryResponse, WorkerSubmitAgentTaskEvalRequest, WorkerSubmitAgentTaskEvalResponse, WorkerSubmitAgentTaskReviewRequest, WorkerSubmitAgentTaskReviewResponse, WorkerUpdateIntentRequest, WorkerUpdateIntentResponse, XPendingSignupResponse } from '@playdrop/types';
|
|
1
|
+
import type { AbortAppUploadResponse, AbortAssetPackUploadResponse, AdInterstitialShowResponse, AdLoadRequest, AdLoadResponse, AdRewardedShowResponse, AdShowRequest, AdminAgentTaskDetailResponse, AdminAgentTaskTranscriptResponse, AdminAgentTasksResponse, AdminAgentWorkersStatusResponse, AdminAppPlayerMetaResponse, AdminAppPlayerMetaUserResponse, AdminAppVersionReviewsListResponse, AdminAppsListResponse, AdminCreatorEngagementExecutionsResponse, AdminCreatorEngagementRulePreviewRequest, AdminCreatorEngagementRulePreviewResponse, AdminCreatorEngagementRulesResponse, AdminCreatorEngagementUserResponse, AdminCreditTransactionsResponse, AdminEnqueueNextAppVersionReviewTaskResponse, AdminFeedbackListResponse, AdminFeedbackResponse, AdminGameCollectionCandidatesResponse, AdminGameCollectionResponse, AdminGameCollectionsResponse, AdminMutateAchievementStateRequest, AdminMutateAchievementStateResponse, AdminMutateLeaderboardScoreRequest, AdminMutateLeaderboardScoreResponse, AdminPaymentDetailResponse, AdminPaymentsListResponse, AdminPlatformAnalyticsRequest, AdminPlatformAnalyticsResponse, 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, AppMoreCollectionKey, AppMoreCollectionPage, AppMoreCollectionRequest, AppMoreCollectionsRequest, AppMoreCollectionsResponse, AppRuntimeAssetsResponse, AppSourceBundleResponse, AppType, AppUploadLaunchCheckPreviewResponse, AppVersionDetailResponse, AppVersionVisibility, 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, CreateRemixGameAgentTaskRequest, CreateRemixGameAgentTaskResponse, CreateTagGroupRequest, CreateTagRequest, CreateUserRequest, CreateUserResponse, CreatorAppsBrowseRequest, CreatorBlockMutationResponse, CreatorEarningsResponse, CreatorEngagementRuleExecutionStatus, CreatorFollowMutationResponse, CreatorGameCreatorFeedbackStatusResponse, CreatorGameShareResponse, CreatorGameStatusResponse, CreatorGameVersionsResponse, CreatorGamesListResponse, CreditPackCheckoutSessionRequest, CreditPackCheckoutSessionResponse, CreditPackCheckoutStatusResponse, 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, FinalizeAssetPackUploadResponse, FirebasePushDeviceRequest, FirebasePushDeviceStatusResponse, 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, 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, WorkerCreateAgentTaskEventRequest, WorkerCreateAgentTaskEventResponse, WorkerCreateAgentTaskTranscriptChunkRequest, WorkerCreateAgentTaskTranscriptChunkResponse, WorkerFailAgentTaskRequest, WorkerHeartbeatAgentTaskRequest, WorkerHeartbeatAgentTaskResponse, WorkerPresenceRequest, WorkerPresenceResponse, RegisterAgentBundleRequest, RegisterAgentBundleResponse, WorkerRecordAgentTaskRunTelemetryRequest, WorkerRecordAgentTaskRunTelemetryResponse, WorkerSubmitAgentTaskEvalRequest, WorkerSubmitAgentTaskEvalResponse, WorkerSubmitAgentTaskReviewRequest, WorkerSubmitAgentTaskReviewResponse, WorkerUpdateIntentRequest, WorkerUpdateIntentResponse, XPendingSignupResponse } from '@playdrop/types';
|
|
2
2
|
import { type AdminAgentTaskTranscriptOptions, type ListAgentTasksOptions, type ListCreatorGamesOptions } from './domains/agent-tasks.js';
|
|
3
3
|
export interface HttpMethod {
|
|
4
4
|
GET: 'GET';
|
|
@@ -464,6 +464,7 @@ export interface ApiClient {
|
|
|
464
464
|
finalizeAppUpload(creatorUsername: string, appName: string, sessionId: string): Promise<FinalizeAppUploadResponse>;
|
|
465
465
|
fetchAppUploadLaunchCheckPreview(creatorUsername: string, appName: string, sessionId: string): Promise<AppUploadLaunchCheckPreviewResponse>;
|
|
466
466
|
recordAppUploadLaunchCheck(creatorUsername: string, appName: string, sessionId: string, request: RecordAppUploadLaunchCheckRequest): Promise<RecordAppUploadLaunchCheckResponse>;
|
|
467
|
+
recordAppUploadCausalCheck(creatorUsername: string, appName: string, sessionId: string, request: RecordAppUploadCausalCheckRequest): Promise<RecordAppUploadCausalCheckResponse>;
|
|
467
468
|
recordAppUploadMediaCapture(creatorUsername: string, appName: string, sessionId: string, request: RecordAppUploadMediaCaptureRequest): Promise<RecordAppUploadMediaCaptureResponse>;
|
|
468
469
|
abortAppUpload(creatorUsername: string, appName: string, sessionId: string): Promise<AbortAppUploadResponse>;
|
|
469
470
|
listAppVersions(creatorUsername: string, appName: string): Promise<AppVersionsListResponse>;
|