@playdrop/playdrop-cli 0.15.6 → 0.15.11
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 +2 -3
- package/dist/apps/index.js +2 -2
- package/dist/apps/loadCheck.d.ts +4 -1
- package/dist/apps/loadCheck.js +64 -7
- package/dist/apps/staticHtml.js +1 -0
- package/dist/apps/upload.d.ts +38 -1
- package/dist/apps/upload.js +58 -44
- package/dist/catalogue.d.ts +3 -0
- package/dist/catalogue.js +26 -0
- package/dist/commands/create.js +45 -16
- package/dist/commands/devRuntimeAssets.d.ts +1 -0
- package/dist/commands/devRuntimeAssets.js +2 -0
- package/dist/commands/review.js +0 -3
- package/dist/commands/upload.d.ts +2 -3
- package/dist/commands/upload.js +23 -42
- package/dist/commands/validate.js +0 -4
- package/dist/commands/worker.d.ts +7 -1
- package/dist/commands/worker.js +65 -57
- package/dist/index.js +1 -1
- package/dist/listingPreflight.d.ts +1 -24
- package/dist/listingPreflight.js +3 -288
- package/node_modules/@playdrop/api-client/dist/client.d.ts +25 -2
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/client.js +11 -0
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts +4 -1
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/admin.js +31 -2
- package/node_modules/@playdrop/api-client/dist/domains/agent-tasks.d.ts +2 -1
- package/node_modules/@playdrop/api-client/dist/domains/agent-tasks.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/agent-tasks.js +12 -0
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts +9 -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 +66 -0
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts +1 -0
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.js +3 -0
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts +1 -0
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/assets.js +3 -0
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts +10 -2
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/payments.js +66 -1
- package/node_modules/@playdrop/api-client/dist/index.d.ts +27 -5
- package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.js +73 -2
- package/node_modules/@playdrop/config/client-meta.json +2 -2
- package/node_modules/@playdrop/config/dist/src/creator-plans.d.ts +18 -0
- package/node_modules/@playdrop/config/dist/src/creator-plans.d.ts.map +1 -0
- package/node_modules/@playdrop/config/dist/src/creator-plans.js +117 -0
- package/node_modules/@playdrop/config/dist/src/game-arena.d.ts +1 -1
- package/node_modules/@playdrop/config/dist/src/game-arena.js +1 -1
- package/node_modules/@playdrop/config/dist/src/index.d.ts +1 -0
- package/node_modules/@playdrop/config/dist/src/index.d.ts.map +1 -1
- package/node_modules/@playdrop/config/dist/src/index.js +1 -0
- package/node_modules/@playdrop/config/dist/test/creator-plans.test.d.ts +2 -0
- package/node_modules/@playdrop/config/dist/test/creator-plans.test.d.ts.map +1 -0
- package/node_modules/@playdrop/config/dist/test/creator-plans.test.js +28 -0
- package/node_modules/@playdrop/config/dist/test/game-arena.test.js +3 -3
- package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@playdrop/types/dist/api.d.ts +153 -15
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/api.js +27 -2
- package/node_modules/@playdrop/types/dist/app-review.d.ts +2 -0
- package/node_modules/@playdrop/types/dist/app-review.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/app-review.js +31 -2
- package/node_modules/@playdrop/types/dist/index.d.ts +2 -0
- package/node_modules/@playdrop/types/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/index.js +5 -1
- package/node_modules/@playdrop/types/dist/locale.d.ts +5 -0
- package/node_modules/@playdrop/types/dist/locale.d.ts.map +1 -0
- package/node_modules/@playdrop/types/dist/locale.js +47 -0
- package/node_modules/@playdrop/types/dist/release-smoke.d.ts +3 -0
- package/node_modules/@playdrop/types/dist/release-smoke.d.ts.map +1 -0
- package/node_modules/@playdrop/types/dist/release-smoke.js +35 -0
- package/node_modules/@playdrop/types/dist/version.d.ts +5 -0
- package/node_modules/@playdrop/types/dist/version.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/commands/create.js
CHANGED
|
@@ -20,6 +20,7 @@ const catalogue_utils_1 = require("../catalogue-utils");
|
|
|
20
20
|
const clientInfo_1 = require("../clientInfo");
|
|
21
21
|
const commandContext_1 = require("../commandContext");
|
|
22
22
|
const http_1 = require("../http");
|
|
23
|
+
const listingPreflight_1 = require("../listingPreflight");
|
|
23
24
|
const messages_1 = require("../messages");
|
|
24
25
|
const loadCheck_1 = require("../apps/loadCheck");
|
|
25
26
|
const devShared_1 = require("./devShared");
|
|
@@ -252,6 +253,28 @@ function makeDefaultAssetSpecEntry(name) {
|
|
|
252
253
|
visibility: 'PUBLIC',
|
|
253
254
|
};
|
|
254
255
|
}
|
|
256
|
+
function resolveTaskScaffoldOutputVersion(startDir = process.cwd()) {
|
|
257
|
+
const context = (0, listingPreflight_1.readWorkerUploadPreflightContext)(startDir);
|
|
258
|
+
if (!context || (context.kind !== 'NEW_GAME' && context.kind !== 'REMIX_GAME')) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
if (!context.outputVersion) {
|
|
262
|
+
throw new Error('agent_task_output_version_missing: task.metadata.playdrop.output.version is required when scaffolding a game task.');
|
|
263
|
+
}
|
|
264
|
+
return context.outputVersion;
|
|
265
|
+
}
|
|
266
|
+
function forceScaffoldedCatalogueVersion(cataloguePath, appName, outputVersion) {
|
|
267
|
+
const parsed = readCatalogue(cataloguePath);
|
|
268
|
+
if (!parsed || !Array.isArray(parsed.apps)) {
|
|
269
|
+
throw new Error(`agent_task_scaffold_catalogue_invalid: ${cataloguePath} must contain an apps array.`);
|
|
270
|
+
}
|
|
271
|
+
const app = parsed.apps.find((entry) => entry?.name === appName);
|
|
272
|
+
if (!app) {
|
|
273
|
+
throw new Error(`agent_task_scaffold_app_missing: ${cataloguePath} must contain app "${appName}".`);
|
|
274
|
+
}
|
|
275
|
+
app.version = outputVersion;
|
|
276
|
+
(0, node_fs_1.writeFileSync)(cataloguePath, `${JSON.stringify(parsed, null, 2)}\n`);
|
|
277
|
+
}
|
|
255
278
|
function buildCatalogueEntry(name, metadata, sourceInfo, relativeFilePath) {
|
|
256
279
|
const entry = makeDefaultAppEntry(name, relativeFilePath);
|
|
257
280
|
if (!metadata) {
|
|
@@ -1133,8 +1156,10 @@ async function create(name, options = {}) {
|
|
|
1133
1156
|
if (!ctx) {
|
|
1134
1157
|
return;
|
|
1135
1158
|
}
|
|
1136
|
-
const envName = ctx.env;
|
|
1137
1159
|
const currentDir = process.cwd();
|
|
1160
|
+
const taskScaffoldOutputVersion = !reuseExistingApp
|
|
1161
|
+
? resolveTaskScaffoldOutputVersion(currentDir)
|
|
1162
|
+
: null;
|
|
1138
1163
|
const localCataloguePath = (0, node_path_1.resolve)(currentDir, CATALOGUE_FILENAME);
|
|
1139
1164
|
let initSummary = null;
|
|
1140
1165
|
let workspaceCatalogueResult = null;
|
|
@@ -1365,6 +1390,21 @@ async function create(name, options = {}) {
|
|
|
1365
1390
|
return;
|
|
1366
1391
|
}
|
|
1367
1392
|
}
|
|
1393
|
+
if (taskScaffoldOutputVersion) {
|
|
1394
|
+
const scaffoldedCataloguePaths = new Set();
|
|
1395
|
+
if (projectCatalogueResult?.updated) {
|
|
1396
|
+
scaffoldedCataloguePaths.add((0, node_path_1.resolve)(projectCatalogueResult.path));
|
|
1397
|
+
}
|
|
1398
|
+
if (workspaceCatalogueResult && workspaceCatalogueUpdateSucceeded) {
|
|
1399
|
+
scaffoldedCataloguePaths.add((0, node_path_1.resolve)(workspaceCatalogueResult.path));
|
|
1400
|
+
}
|
|
1401
|
+
if (scaffoldedCataloguePaths.size === 0) {
|
|
1402
|
+
throw new Error('agent_task_scaffold_catalogue_missing: scaffolding did not produce a catalogue to version.');
|
|
1403
|
+
}
|
|
1404
|
+
for (const scaffoldedCataloguePath of scaffoldedCataloguePaths) {
|
|
1405
|
+
forceScaffoldedCatalogueVersion(scaffoldedCataloguePath, name, taskScaffoldOutputVersion);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1368
1408
|
let registrationTask = null;
|
|
1369
1409
|
if (reuseExistingApp && existingTask) {
|
|
1370
1410
|
registrationTask = existingTask;
|
|
@@ -1455,6 +1495,7 @@ async function create(name, options = {}) {
|
|
|
1455
1495
|
name,
|
|
1456
1496
|
displayName,
|
|
1457
1497
|
...(Number.isInteger(taskId) && Number(taskId) > 0 ? { agentTaskId: Number(taskId) } : {}),
|
|
1498
|
+
...(sourceInfo.remixRef ? { remixRef: sourceInfo.remixRef } : {}),
|
|
1458
1499
|
};
|
|
1459
1500
|
let creatorUsername = '';
|
|
1460
1501
|
try {
|
|
@@ -1487,7 +1528,6 @@ async function create(name, options = {}) {
|
|
|
1487
1528
|
}
|
|
1488
1529
|
throw error;
|
|
1489
1530
|
}
|
|
1490
|
-
let createConflict = false;
|
|
1491
1531
|
try {
|
|
1492
1532
|
await client.createApp(creatorUsername, createPayload);
|
|
1493
1533
|
console.log(`Registered ${displayName} with the Playdrop API.`);
|
|
@@ -1503,17 +1543,9 @@ async function create(name, options = {}) {
|
|
|
1503
1543
|
return;
|
|
1504
1544
|
}
|
|
1505
1545
|
if (error instanceof types_1.ApiError) {
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
}
|
|
1510
|
-
else {
|
|
1511
|
-
(0, messages_1.printErrorWithHelp)(`Failed to register ${name} (status ${error.status}).`, [
|
|
1512
|
-
'Ensure your account has creator permissions and retry once the issue is resolved.'
|
|
1513
|
-
], { command: 'project create app' });
|
|
1514
|
-
process.exitCode = 1;
|
|
1515
|
-
return;
|
|
1516
|
-
}
|
|
1546
|
+
(0, messages_1.printErrorWithHelp)(`Failed to register ${name} (status ${error.status}: ${error.code}).`, ['Resolve the API error, then retry the same project create command.'], { command: 'project create app' });
|
|
1547
|
+
process.exitCode = 1;
|
|
1548
|
+
return;
|
|
1517
1549
|
}
|
|
1518
1550
|
else if (error instanceof TypeError) {
|
|
1519
1551
|
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to register the app.', 'project create app');
|
|
@@ -1535,9 +1567,6 @@ async function create(name, options = {}) {
|
|
|
1535
1567
|
if (Object.keys(updatePayload).length > 0) {
|
|
1536
1568
|
try {
|
|
1537
1569
|
await client.updateApp(creatorUsername, name, updatePayload);
|
|
1538
|
-
if (createConflict) {
|
|
1539
|
-
console.log(`Updated ${name} metadata on the Playdrop API.`);
|
|
1540
|
-
}
|
|
1541
1570
|
}
|
|
1542
1571
|
catch (error) {
|
|
1543
1572
|
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
@@ -12,6 +12,7 @@ export type LocalDevAppMetadata = {
|
|
|
12
12
|
authMode: AppAuthMode;
|
|
13
13
|
controllerMode: AppControllerMode;
|
|
14
14
|
previewable: boolean;
|
|
15
|
+
editorSupported: boolean;
|
|
15
16
|
assetSpecSupport: AppMetadataAssetSpecSupport[];
|
|
16
17
|
version: string | null;
|
|
17
18
|
tweakValues?: TweakValues;
|
|
@@ -20,6 +20,7 @@ function createEmptyDevRuntimeAssetManifest() {
|
|
|
20
20
|
authMode: types_1.DEFAULT_APP_AUTH_MODE,
|
|
21
21
|
controllerMode: types_1.DEFAULT_APP_CONTROLLER_MODE,
|
|
22
22
|
previewable: types_1.DEFAULT_APP_PREVIEWABLE,
|
|
23
|
+
editorSupported: false,
|
|
23
24
|
assetSpecSupport: [],
|
|
24
25
|
version: null,
|
|
25
26
|
},
|
|
@@ -118,6 +119,7 @@ function buildLocalAppMetadata(task) {
|
|
|
118
119
|
authMode: task.authMode ?? types_1.DEFAULT_APP_AUTH_MODE,
|
|
119
120
|
controllerMode: task.controllerMode ?? types_1.DEFAULT_APP_CONTROLLER_MODE,
|
|
120
121
|
previewable: task.previewable ?? types_1.DEFAULT_APP_PREVIEWABLE,
|
|
122
|
+
editorSupported: task.editorSupported ?? false,
|
|
121
123
|
assetSpecSupport: task.assetSpecSupport.map((entry) => ({
|
|
122
124
|
assetSpecRef: entry.assetSpec,
|
|
123
125
|
versionRange: entry.versionRange,
|
package/dist/commands/review.js
CHANGED
|
@@ -87,9 +87,6 @@ function normalizeReviewText(...values) {
|
|
|
87
87
|
.trim();
|
|
88
88
|
}
|
|
89
89
|
function parseScores(reviewMessage) {
|
|
90
|
-
if (/\/5\b/.test(reviewMessage)) {
|
|
91
|
-
throw new Error('review_scores_must_use_10_point_scale');
|
|
92
|
-
}
|
|
93
90
|
const scores = {};
|
|
94
91
|
for (const criterion of exports.REVIEW_CRITERIA) {
|
|
95
92
|
const escaped = criterion.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
@@ -51,6 +51,7 @@ export type StaticHtmlPublishInput = {
|
|
|
51
51
|
taskToken?: string;
|
|
52
52
|
claimedAppName?: string | null;
|
|
53
53
|
devRouterPort?: number;
|
|
54
|
+
skipReview?: boolean;
|
|
54
55
|
};
|
|
55
56
|
export type StaticHtmlPublishResult = WorkerAppPublishResult & {
|
|
56
57
|
sourceHash: string;
|
|
@@ -62,12 +63,10 @@ export type StaticHtmlPublishResult = WorkerAppPublishResult & {
|
|
|
62
63
|
};
|
|
63
64
|
export declare function assertAgentPrimarySurfaceContract(task: AppTask, kind: 'NEW_GAME' | 'REMIX_GAME' | 'GAME_UPDATE'): void;
|
|
64
65
|
export declare function assertAgentNewGamePlaytestContract(task: AppTask): void;
|
|
66
|
+
export declare function assertAgentNewGameListingIdentity(task: AppTask): void;
|
|
65
67
|
export declare function assertWorkerAppLocalUploadPreflight(input: {
|
|
66
68
|
task: AppTask;
|
|
67
69
|
kind: 'NEW_GAME' | 'REMIX_GAME' | 'GAME_UPDATE';
|
|
68
|
-
executionTarget?: AgentExecutionTarget;
|
|
69
|
-
stage?: 'PRE_CAPTURE' | 'COMPLETE';
|
|
70
|
-
expectedRuntimeBundleHash?: string;
|
|
71
70
|
}): Promise<void>;
|
|
72
71
|
export type WorkerAppPreflightResult = {
|
|
73
72
|
appName: string;
|
package/dist/commands/upload.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.resolveDefaultUploadCreator = resolveDefaultUploadCreator;
|
|
|
5
5
|
exports.upload = upload;
|
|
6
6
|
exports.assertAgentPrimarySurfaceContract = assertAgentPrimarySurfaceContract;
|
|
7
7
|
exports.assertAgentNewGamePlaytestContract = assertAgentNewGamePlaytestContract;
|
|
8
|
+
exports.assertAgentNewGameListingIdentity = assertAgentNewGameListingIdentity;
|
|
8
9
|
exports.assertWorkerAppLocalUploadPreflight = assertWorkerAppLocalUploadPreflight;
|
|
9
10
|
exports.preflightWorkerAppProject = preflightWorkerAppProject;
|
|
10
11
|
exports.publishWorkerAppProject = publishWorkerAppProject;
|
|
@@ -28,7 +29,6 @@ const workerAppProject_1 = require("../workerAppProject");
|
|
|
28
29
|
const upload_content_1 = require("./upload-content");
|
|
29
30
|
const appUrls_1 = require("../appUrls");
|
|
30
31
|
const ownedRuntimeImageValidation_1 = require("./ownedRuntimeImageValidation");
|
|
31
|
-
const listingPreflight_1 = require("../listingPreflight");
|
|
32
32
|
const upload_graph_1 = require("./upload-graph");
|
|
33
33
|
function normalizeSavedItemKinds(kinds) {
|
|
34
34
|
return [...new Set(Array.isArray(kinds) ? kinds : [])].sort();
|
|
@@ -841,7 +841,6 @@ function appendTaskRelations(graphState, fromNodeId, relations, contextLabel) {
|
|
|
841
841
|
});
|
|
842
842
|
}
|
|
843
843
|
async function uploadAppTask(state, task, taskCreator, options) {
|
|
844
|
-
(0, listingPreflight_1.assertProjectListingPreflight)(task);
|
|
845
844
|
const { upload, warnings } = await (0, apps_1.runAppPipeline)(state.client, task, {
|
|
846
845
|
skipReview: options?.skipReview,
|
|
847
846
|
clearTags: options?.clearTags,
|
|
@@ -1266,6 +1265,18 @@ function assertAgentNewGamePlaytestContract(task) {
|
|
|
1266
1265
|
}
|
|
1267
1266
|
}
|
|
1268
1267
|
}
|
|
1268
|
+
function assertAgentNewGameListingIdentity(task) {
|
|
1269
|
+
const missing = [];
|
|
1270
|
+
if (!task.listing?.iconPath)
|
|
1271
|
+
missing.push('listing.icon');
|
|
1272
|
+
if (!task.listing?.heroPortraitPath)
|
|
1273
|
+
missing.push('listing.hero.portrait');
|
|
1274
|
+
if (!task.listing?.heroLandscapePath)
|
|
1275
|
+
missing.push('listing.hero.landscape');
|
|
1276
|
+
if (missing.length > 0) {
|
|
1277
|
+
throw new Error(`agent_task_listing_identity_required: NEW_GAME catalogue.json must provide ${missing.join(', ')}.`);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1269
1280
|
async function collectUploadPreflightErrors(checks) {
|
|
1270
1281
|
const errors = [];
|
|
1271
1282
|
for (const check of checks) {
|
|
@@ -1291,42 +1302,15 @@ function assertAgentTaskReleaseNotes(task) {
|
|
|
1291
1302
|
}
|
|
1292
1303
|
}
|
|
1293
1304
|
async function assertWorkerAppLocalUploadPreflight(input) {
|
|
1294
|
-
const complete = input.stage !== 'PRE_CAPTURE';
|
|
1295
|
-
const existingCaptureReport = input.task.listing?.captureReportPath;
|
|
1296
|
-
const shouldCheckExistingCapture = !complete
|
|
1297
|
-
&& Boolean(existingCaptureReport)
|
|
1298
|
-
&& (0, node_fs_1.existsSync)(existingCaptureReport);
|
|
1299
1305
|
const errors = await collectUploadPreflightErrors([
|
|
1300
1306
|
() => assertAgentTaskReleaseNotes(input.task),
|
|
1301
|
-
...(
|
|
1307
|
+
...(input.kind === 'NEW_GAME'
|
|
1302
1308
|
? [
|
|
1303
|
-
() => (
|
|
1304
|
-
() => (
|
|
1305
|
-
() => (0, listingPreflight_1.assertAgentGamePreviewListingPreflight)(input.task),
|
|
1306
|
-
() => (0, listingPreflight_1.assertAgentGameVideoListingPreflight)(input.task),
|
|
1309
|
+
() => assertAgentNewGamePlaytestContract(input.task),
|
|
1310
|
+
() => assertAgentNewGameListingIdentity(input.task),
|
|
1307
1311
|
]
|
|
1308
|
-
: []),
|
|
1309
|
-
...(input.kind === 'NEW_GAME'
|
|
1310
|
-
? [() => assertAgentNewGamePlaytestContract(input.task)]
|
|
1311
1312
|
: [() => assertAgentPrimarySurfaceContract(input.task, input.kind)]),
|
|
1312
1313
|
() => (0, ownedRuntimeImageValidation_1.assertOwnedRuntimeImagesAreValid)(input.task),
|
|
1313
|
-
...(complete
|
|
1314
|
-
? [
|
|
1315
|
-
() => (0, listingPreflight_1.assertAgentGameScreenshotListingPreflight)(input.task),
|
|
1316
|
-
() => (0, listingPreflight_1.assertAgentGameCaptureReportPreflight)(input.task, {
|
|
1317
|
-
requireCaptureReport: input.executionTarget === 'FIRST_PARTY',
|
|
1318
|
-
expectedRuntimeBundleHash: input.expectedRuntimeBundleHash,
|
|
1319
|
-
}),
|
|
1320
|
-
]
|
|
1321
|
-
: []),
|
|
1322
|
-
...(shouldCheckExistingCapture
|
|
1323
|
-
? [
|
|
1324
|
-
() => (0, listingPreflight_1.assertAgentGameCaptureReportPreflight)(input.task, {
|
|
1325
|
-
requireCaptureReport: false,
|
|
1326
|
-
expectedRuntimeBundleHash: input.expectedRuntimeBundleHash,
|
|
1327
|
-
}),
|
|
1328
|
-
]
|
|
1329
|
-
: []),
|
|
1330
1314
|
]);
|
|
1331
1315
|
if (errors.length === 1) {
|
|
1332
1316
|
throw new Error(errors[0]);
|
|
@@ -1335,7 +1319,7 @@ async function assertWorkerAppLocalUploadPreflight(input) {
|
|
|
1335
1319
|
throw new Error(`agent_task_upload_preflight_failed:\n${errors.map((error, index) => `${index + 1}. ${error}`).join('\n')}`);
|
|
1336
1320
|
}
|
|
1337
1321
|
}
|
|
1338
|
-
async function prepareWorkerAppProject(input
|
|
1322
|
+
async function prepareWorkerAppProject(input) {
|
|
1339
1323
|
const creatorUsername = input.creatorUsername.trim();
|
|
1340
1324
|
if (!creatorUsername) {
|
|
1341
1325
|
throw new Error('agent_task_creator_username_missing');
|
|
@@ -1390,9 +1374,6 @@ async function prepareWorkerAppProject(input, stage) {
|
|
|
1390
1374
|
await assertWorkerAppLocalUploadPreflight({
|
|
1391
1375
|
task,
|
|
1392
1376
|
kind: input.kind,
|
|
1393
|
-
executionTarget: input.executionTarget,
|
|
1394
|
-
stage,
|
|
1395
|
-
expectedRuntimeBundleHash: artifacts?.bundleHash,
|
|
1396
1377
|
});
|
|
1397
1378
|
return {
|
|
1398
1379
|
task,
|
|
@@ -1401,11 +1382,12 @@ async function prepareWorkerAppProject(input, stage) {
|
|
|
1401
1382
|
creatorUsername,
|
|
1402
1383
|
};
|
|
1403
1384
|
}
|
|
1404
|
-
// Runs every worker upload check
|
|
1405
|
-
//
|
|
1385
|
+
// Runs every worker upload check without publishing. It intentionally performs
|
|
1386
|
+
// no app registration, metadata
|
|
1406
1387
|
// update, upload-session creation, file upload, or version creation.
|
|
1407
1388
|
async function preflightWorkerAppProject(input) {
|
|
1408
|
-
const prepared = await prepareWorkerAppProject(input
|
|
1389
|
+
const prepared = await prepareWorkerAppProject(input);
|
|
1390
|
+
await (0, apps_1.prepareAppUploadFiles)(prepared.task, prepared.artifacts);
|
|
1409
1391
|
return {
|
|
1410
1392
|
appName: prepared.task.name,
|
|
1411
1393
|
creatorUsername: prepared.creatorUsername,
|
|
@@ -1416,7 +1398,7 @@ async function preflightWorkerAppProject(input) {
|
|
|
1416
1398
|
// "playdrop project publish", but always as one PRIVATE draft version for the
|
|
1417
1399
|
// task's creator, with browser launch checks on before the version is created.
|
|
1418
1400
|
async function publishWorkerAppProject(input) {
|
|
1419
|
-
const prepared = await prepareWorkerAppProject(input
|
|
1401
|
+
const prepared = await prepareWorkerAppProject(input);
|
|
1420
1402
|
const { task, artifacts, creatorUsername } = prepared;
|
|
1421
1403
|
const { app } = await (0, registration_1.ensureRegisteredHostedAppShell)({
|
|
1422
1404
|
client: input.client,
|
|
@@ -1446,7 +1428,6 @@ async function publishWorkerAppProject(input) {
|
|
|
1446
1428
|
runStagedUploadLoadCheck: true,
|
|
1447
1429
|
ensureRegisteredAppShell: true,
|
|
1448
1430
|
agentTaskId: input.taskId,
|
|
1449
|
-
mediaCaptureRequired: input.executionTarget === 'FIRST_PARTY',
|
|
1450
1431
|
playtestSmokeCheckRequired: input.kind === 'NEW_GAME',
|
|
1451
1432
|
captureSession,
|
|
1452
1433
|
...(artifacts ? { artifacts } : {}),
|
|
@@ -1536,8 +1517,8 @@ async function publishStaticHtmlProject(input) {
|
|
|
1536
1517
|
runStagedUploadLoadCheck: true,
|
|
1537
1518
|
ensureRegisteredAppShell: true,
|
|
1538
1519
|
agentTaskId: input.taskId,
|
|
1539
|
-
mediaCaptureRequired: false,
|
|
1540
1520
|
playtestSmokeCheckRequired: false,
|
|
1521
|
+
skipReview: input.skipReview,
|
|
1541
1522
|
captureSession,
|
|
1542
1523
|
artifacts: prepared.artifacts,
|
|
1543
1524
|
});
|
|
@@ -212,12 +212,8 @@ async function validate(pathOrName, options = {}) {
|
|
|
212
212
|
await (0, upload_1.assertWorkerAppLocalUploadPreflight)({
|
|
213
213
|
task,
|
|
214
214
|
kind: workerContext.kind,
|
|
215
|
-
executionTarget: workerContext.target,
|
|
216
215
|
});
|
|
217
216
|
}
|
|
218
|
-
else {
|
|
219
|
-
(0, listingPreflight_1.assertProjectListingPreflight)(task);
|
|
220
|
-
}
|
|
221
217
|
await (0, apps_1.validateAppTask)(task);
|
|
222
218
|
(0, apps_1.collectAppValidationWarnings)(task, 'source').forEach((warning) => warnings.add(warning));
|
|
223
219
|
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { ApiClient } from '@playdrop/api-client';
|
|
2
|
-
import { type AgentAvailabilityFailureReason, type AgentExecutionTarget, type AgentRuntime, type AgentTaskKind, type AgentTaskNextStepSuggestion, type AgentTaskResponse, type AppSurface, type AgentWorkerCapabilities, type AgentWorkerResponse, type AgentWorkerUpdatePolicyResponse, type JsonValue, type WorkerTaskAssignmentV2, type WorkerTaskPluginV2, type WorkerClaimAgentTaskResponse } from '@playdrop/types';
|
|
2
|
+
import { RELEASE_SMOKE_FILE_NAME, type AgentAvailabilityFailureReason, type AgentExecutionTarget, type AgentRuntime, type AgentTaskKind, type AgentTaskNextStepSuggestion, type AgentTaskResponse, type AppSurface, type AgentWorkerCapabilities, type AgentWorkerResponse, type AgentWorkerUpdatePolicyResponse, type JsonValue, type WorkerTaskAssignmentV2, type WorkerTaskPluginV2, type WorkerClaimAgentTaskResponse } from '@playdrop/types';
|
|
3
3
|
import { loadConfig } from '../config';
|
|
4
4
|
import { runShell } from '../shellProbe';
|
|
5
5
|
import { type WorkerInstrumentSurface, type LoggedProcessResult, type LoggedProcessTranscriptChunk } from './worker/runtime';
|
|
6
6
|
export { assertWorkerTokenUsageWithinCap, buildClaudeExecArgs, buildClaudePermissionSettings, buildCleanRoomChildEnv, buildCodexExecArgs, buildPlaywrightMcpCommand, buildWorkerChildEnv, DEFAULT_CODEX_TIMEOUT_MS, DEFAULT_CREATOR_AGENT_TIMEOUT_MS, DEFAULT_CREATOR_UPLOAD_RECOVERY_TIMEOUT_MS, DEFAULT_WORKER_TOKEN_CAP, extractAgentTokenUsage, extractCodexRolloutTokenUsage, extractClaudeSessionId, extractCodexThreadId, extractCodexTokensUsed, readCodexRolloutTokenUsageForThread, readCodexSandboxMode, readEnvBoolean, runLoggedProcess } from './worker/runtime';
|
|
7
7
|
export type { AgentTokenUsage, LoggedProcessResult, LoggedProcessTranscriptChunk } from './worker/runtime';
|
|
8
8
|
export declare function usesCreatorRecovery(kind: AgentTaskKind): boolean;
|
|
9
|
+
export declare function buildDeterministicReleaseSmokeArtifact(): {
|
|
10
|
+
fileName: typeof RELEASE_SMOKE_FILE_NAME;
|
|
11
|
+
content: Buffer;
|
|
12
|
+
sha256: string;
|
|
13
|
+
};
|
|
9
14
|
export declare function buildCreatorRecoveryPrompt(input: {
|
|
10
15
|
prompt: string;
|
|
11
16
|
kind: AgentTaskKind;
|
|
@@ -204,6 +209,7 @@ export declare function prepareClaimedTaskWorkspace(input: {
|
|
|
204
209
|
}): Promise<{
|
|
205
210
|
resumed: boolean;
|
|
206
211
|
}>;
|
|
212
|
+
export declare function buildWorkerTaskContextV2(assignment: WorkerTaskAssignmentV2): Omit<WorkerTaskContextFile, 'env' | 'devPort'>;
|
|
207
213
|
export declare function resolveWorkerInstrumentSurface(taskContext: Pick<WorkerTaskContextFile, 'kind' | 'metadata'>): WorkerInstrumentSurface | null;
|
|
208
214
|
export declare function hasAgentTaskUploadedArtifact(task: Pick<AgentTaskResponse, 'appId' | 'appVersionId'>): boolean;
|
|
209
215
|
export declare function appendWorkerTranscriptChunks(input: {
|
package/dist/commands/worker.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
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;
|
|
7
7
|
exports.usesCreatorRecovery = usesCreatorRecovery;
|
|
8
|
+
exports.buildDeterministicReleaseSmokeArtifact = buildDeterministicReleaseSmokeArtifact;
|
|
8
9
|
exports.buildCreatorRecoveryPrompt = buildCreatorRecoveryPrompt;
|
|
9
10
|
exports.buildGameEvalRetryPrompt = buildGameEvalRetryPrompt;
|
|
10
11
|
exports.resolveInitialCreatorProgress = resolveInitialCreatorProgress;
|
|
@@ -17,6 +18,7 @@ exports.claimBackoffDelayMs = claimBackoffDelayMs;
|
|
|
17
18
|
exports.resolveWorkerHomeDir = resolveWorkerHomeDir;
|
|
18
19
|
exports.pruneWorkerTaskWorkspaces = pruneWorkerTaskWorkspaces;
|
|
19
20
|
exports.prepareClaimedTaskWorkspace = prepareClaimedTaskWorkspace;
|
|
21
|
+
exports.buildWorkerTaskContextV2 = buildWorkerTaskContextV2;
|
|
20
22
|
exports.resolveWorkerInstrumentSurface = resolveWorkerInstrumentSurface;
|
|
21
23
|
exports.hasAgentTaskUploadedArtifact = hasAgentTaskUploadedArtifact;
|
|
22
24
|
exports.appendWorkerTranscriptChunks = appendWorkerTranscriptChunks;
|
|
@@ -111,7 +113,6 @@ const commandContext_1 = require("../commandContext");
|
|
|
111
113
|
const config_1 = require("../config");
|
|
112
114
|
const messages_1 = require("../messages");
|
|
113
115
|
const output_1 = require("../output");
|
|
114
|
-
const recorderRelease_1 = require("../recorderRelease");
|
|
115
116
|
const shellProbe_1 = require("../shellProbe");
|
|
116
117
|
const review_1 = require("./review");
|
|
117
118
|
const upload_1 = require("./upload");
|
|
@@ -152,7 +153,7 @@ const FAIL_REPORT_RETRY_DELAY_MS = 2000;
|
|
|
152
153
|
const WORKER_TRANSCRIPT_CHUNK_BATCH_SIZE = 100;
|
|
153
154
|
const SLACK_API_BASE_URL = 'https://slack.com/api';
|
|
154
155
|
const WORKER_WRAPPER_CONTRACT_VERSION = 3;
|
|
155
|
-
const WORKER_SUPPORTED_KINDS = ['NEW_GAME', 'STATIC_GAME', 'REMIX_GAME', 'GAME_UPDATE', 'GAME_REVIEW', 'GAME_EVAL'];
|
|
156
|
+
const WORKER_SUPPORTED_KINDS = ['NEW_GAME', 'STATIC_GAME', 'REMIX_GAME', 'GAME_UPDATE', 'GAME_REVIEW', 'GAME_EVAL', 'RELEASE_SMOKE'];
|
|
156
157
|
const GAME_CREATION_TASK_KINDS = new Set(['NEW_GAME', 'STATIC_GAME', 'REMIX_GAME', 'GAME_UPDATE']);
|
|
157
158
|
const AGENT_MANAGED_UPLOAD_TASK_KINDS = new Set(['NEW_GAME', 'REMIX_GAME', 'GAME_UPDATE']);
|
|
158
159
|
const requireFromWorker = (0, node_module_1.createRequire)(__filename);
|
|
@@ -168,6 +169,14 @@ const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
|
168
169
|
function usesCreatorRecovery(kind) {
|
|
169
170
|
return GAME_CREATION_TASK_KINDS.has(kind);
|
|
170
171
|
}
|
|
172
|
+
function buildDeterministicReleaseSmokeArtifact() {
|
|
173
|
+
const content = Buffer.from(types_1.RELEASE_SMOKE_HTML, 'utf8');
|
|
174
|
+
return {
|
|
175
|
+
fileName: types_1.RELEASE_SMOKE_FILE_NAME,
|
|
176
|
+
content,
|
|
177
|
+
sha256: (0, node_crypto_1.createHash)('sha256').update(content).digest('hex'),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
171
180
|
function buildCreatorRecoveryPrompt(input) {
|
|
172
181
|
const prompt = input.prompt.trim();
|
|
173
182
|
if (!prompt) {
|
|
@@ -610,7 +619,7 @@ function buildWorkerTaskContext(input) {
|
|
|
610
619
|
}
|
|
611
620
|
const metadata = playdrop;
|
|
612
621
|
const kind = metadata.kind;
|
|
613
|
-
if (kind !== 'NEW_GAME' && kind !== 'STATIC_GAME' && kind !== 'REMIX_GAME' && kind !== 'GAME_UPDATE' && kind !== 'GAME_REVIEW' && kind !== 'GAME_EVAL') {
|
|
622
|
+
if (kind !== 'NEW_GAME' && kind !== 'STATIC_GAME' && kind !== 'REMIX_GAME' && kind !== 'GAME_UPDATE' && kind !== 'GAME_REVIEW' && kind !== 'GAME_EVAL' && kind !== 'RELEASE_SMOKE') {
|
|
614
623
|
throw new Error('agent_task_context_kind_missing');
|
|
615
624
|
}
|
|
616
625
|
const creatorUsername = typeof metadata.creatorUsername === 'string'
|
|
@@ -3004,45 +3013,6 @@ function collectWorkerInfrastructureFailures() {
|
|
|
3004
3013
|
catch (error) {
|
|
3005
3014
|
failures.push(errorCode(error));
|
|
3006
3015
|
}
|
|
3007
|
-
if (node_process_1.default.platform !== 'darwin') {
|
|
3008
|
-
return failures;
|
|
3009
|
-
}
|
|
3010
|
-
if (node_process_1.default.arch !== recorderRelease_1.MAC_WORKER_RECORDER_RELEASE.architecture) {
|
|
3011
|
-
failures.push('worker_preflight_recorder_architecture_unsupported');
|
|
3012
|
-
return failures;
|
|
3013
|
-
}
|
|
3014
|
-
if (!workerCommandExists('ffmpeg')) {
|
|
3015
|
-
failures.push('worker_preflight_ffmpeg_missing');
|
|
3016
|
-
}
|
|
3017
|
-
if (!workerCommandExists('ffprobe')) {
|
|
3018
|
-
failures.push('worker_preflight_ffprobe_missing');
|
|
3019
|
-
}
|
|
3020
|
-
const guiSession = (0, shellProbe_1.runShell)('/bin/launchctl print "gui/$(/usr/bin/id -u)"');
|
|
3021
|
-
if (guiSession.exitCode !== 0) {
|
|
3022
|
-
failures.push('worker_preflight_gui_session_missing');
|
|
3023
|
-
}
|
|
3024
|
-
const recorderPath = (0, recorderRelease_1.resolveMacWorkerRecorderPath)();
|
|
3025
|
-
if (!(0, node_fs_1.existsSync)(recorderPath)) {
|
|
3026
|
-
failures.push('worker_preflight_recorder_missing');
|
|
3027
|
-
return failures;
|
|
3028
|
-
}
|
|
3029
|
-
const recorderStat = (0, node_fs_1.statSync)(recorderPath);
|
|
3030
|
-
if (!recorderStat.isFile() || (recorderStat.mode & 0o111) === 0) {
|
|
3031
|
-
failures.push('worker_preflight_recorder_not_executable');
|
|
3032
|
-
return failures;
|
|
3033
|
-
}
|
|
3034
|
-
const installedSha256 = (0, recorderRelease_1.recorderSha256)((0, node_fs_1.readFileSync)(recorderPath));
|
|
3035
|
-
if (installedSha256 !== recorderRelease_1.MAC_WORKER_RECORDER_RELEASE.sha256) {
|
|
3036
|
-
failures.push('worker_preflight_recorder_hash_mismatch');
|
|
3037
|
-
return failures;
|
|
3038
|
-
}
|
|
3039
|
-
const permission = (0, node_child_process_1.spawnSync)(recorderPath, ['--check-permission'], {
|
|
3040
|
-
encoding: 'utf8',
|
|
3041
|
-
timeout: 10000,
|
|
3042
|
-
});
|
|
3043
|
-
if (permission.status !== 0) {
|
|
3044
|
-
failures.push('worker_preflight_screen_recording_permission_missing');
|
|
3045
|
-
}
|
|
3046
3016
|
return failures;
|
|
3047
3017
|
}
|
|
3048
3018
|
function describeWorkerPreflightReason(reason) {
|
|
@@ -4218,20 +4188,6 @@ async function startWorker(options = {}) {
|
|
|
4218
4188
|
try {
|
|
4219
4189
|
await removeStaleAgentRunCredentials();
|
|
4220
4190
|
const startupFailures = [];
|
|
4221
|
-
if (node_process_1.default.platform === 'darwin') {
|
|
4222
|
-
try {
|
|
4223
|
-
const recorder = await (0, recorderRelease_1.ensureMacWorkerRecorderInstalled)();
|
|
4224
|
-
if (recorder.downloaded) {
|
|
4225
|
-
console.log(`Installed PlayDrop macOS recorder ${recorderRelease_1.MAC_WORKER_RECORDER_RELEASE.version} at ${recorder.path}.`);
|
|
4226
|
-
}
|
|
4227
|
-
}
|
|
4228
|
-
catch (error) {
|
|
4229
|
-
startupFailures.push(`worker_preflight_recorder_download_failed:${errorMessage(error)}`);
|
|
4230
|
-
}
|
|
4231
|
-
}
|
|
4232
|
-
else if (node_process_1.default.platform === 'win32') {
|
|
4233
|
-
console.warn('Native listing recording is not available on Windows yet.');
|
|
4234
|
-
}
|
|
4235
4191
|
const local = collectWorkerLocalStatus();
|
|
4236
4192
|
startupFailures.push(...local.degradedReasons);
|
|
4237
4193
|
if (startupFailures.length > 0 || !local.ready || !local.capabilities || !local.playwright?.chromiumInstalled) {
|
|
@@ -4548,6 +4504,55 @@ async function startWorker(options = {}) {
|
|
|
4548
4504
|
})
|
|
4549
4505
|
: null;
|
|
4550
4506
|
availableSkillPaths = listPluginSkillPaths(assignmentPluginRoot);
|
|
4507
|
+
if (task.kind === 'RELEASE_SMOKE') {
|
|
4508
|
+
if (!assignment.plugin || !assignmentPluginRoot) {
|
|
4509
|
+
throw new Error('release_smoke_bundle_missing');
|
|
4510
|
+
}
|
|
4511
|
+
const artifact = buildDeterministicReleaseSmokeArtifact();
|
|
4512
|
+
const artifactPath = node_path_1.default.join(agentWorkspaceDir, artifact.fileName);
|
|
4513
|
+
await (0, promises_1.writeFile)(artifactPath, artifact.content);
|
|
4514
|
+
const storedArtifact = (0, node_fs_1.readFileSync)(artifactPath);
|
|
4515
|
+
if ((0, node_crypto_1.createHash)('sha256').update(storedArtifact).digest('hex') !== artifact.sha256) {
|
|
4516
|
+
throw new Error('release_smoke_workspace_verification_failed');
|
|
4517
|
+
}
|
|
4518
|
+
if (!envConfig.cdnBase) {
|
|
4519
|
+
throw new Error('release_smoke_publish_cdn_base_missing');
|
|
4520
|
+
}
|
|
4521
|
+
const taskClient = (0, apiClient_1.createCliApiClient)({
|
|
4522
|
+
baseUrl: envConfig.apiBase,
|
|
4523
|
+
token,
|
|
4524
|
+
onBehalfCreatorUsername: taskContext.creatorUsername,
|
|
4525
|
+
agentTaskToken: assignment.task.token,
|
|
4526
|
+
agentTaskId: task.id,
|
|
4527
|
+
agentTaskAttempt: taskContext.attempt,
|
|
4528
|
+
});
|
|
4529
|
+
const published = await (0, upload_1.publishStaticHtmlProject)({
|
|
4530
|
+
client: taskClient,
|
|
4531
|
+
taskId: task.id,
|
|
4532
|
+
taskToken: assignment.task.token,
|
|
4533
|
+
projectDir: agentWorkspaceDir,
|
|
4534
|
+
creatorUsername: taskContext.creatorUsername,
|
|
4535
|
+
primarySurface: 'DESKTOP',
|
|
4536
|
+
apiBase: envConfig.apiBase,
|
|
4537
|
+
webBase: envConfig.webBase ?? null,
|
|
4538
|
+
cdnBase: envConfig.cdnBase,
|
|
4539
|
+
devRouterPort: devPort,
|
|
4540
|
+
token,
|
|
4541
|
+
user: me.user,
|
|
4542
|
+
skipReview: true,
|
|
4543
|
+
});
|
|
4544
|
+
await client.workerCompleteReleaseSmoke(task.id, {
|
|
4545
|
+
workerKey,
|
|
4546
|
+
leaseToken,
|
|
4547
|
+
appId: published.appId,
|
|
4548
|
+
appVersionId: published.appVersionId,
|
|
4549
|
+
sourceSha256: published.sourceHash,
|
|
4550
|
+
runtimeSha256: published.runtimeHash,
|
|
4551
|
+
});
|
|
4552
|
+
retainWorkspace = false;
|
|
4553
|
+
console.log(`Worker release smoke ${task.id} completed without an AI agent.`);
|
|
4554
|
+
return;
|
|
4555
|
+
}
|
|
4551
4556
|
if (cleanRoom) {
|
|
4552
4557
|
const playdropMetadata = assignment.task.metadata.playdrop;
|
|
4553
4558
|
const postAgentAction = playdropMetadata && typeof playdropMetadata === 'object' && !Array.isArray(playdropMetadata)
|
|
@@ -5538,6 +5543,9 @@ async function uploadTask(options = {}) {
|
|
|
5538
5543
|
if (taskContext.kind === 'GAME_REVIEW' || taskContext.kind === 'GAME_EVAL') {
|
|
5539
5544
|
throw new Error('task_upload_not_allowed_for_game_review');
|
|
5540
5545
|
}
|
|
5546
|
+
if (taskContext.kind === 'RELEASE_SMOKE') {
|
|
5547
|
+
throw new Error('task_upload_not_allowed_for_release_smoke');
|
|
5548
|
+
}
|
|
5541
5549
|
const uploadKind = taskContext.kind;
|
|
5542
5550
|
const workspaceDir = resolveTaskWorkspaceDir();
|
|
5543
5551
|
if (options.preflightOnly) {
|
|
@@ -5567,7 +5575,7 @@ async function uploadTask(options = {}) {
|
|
|
5567
5575
|
for (const warning of result.warnings) {
|
|
5568
5576
|
console.error(`Preflight warning: ${warning}`);
|
|
5569
5577
|
}
|
|
5570
|
-
(0, output_1.printSuccess)(`Task upload preflight passed for ${result.creatorUsername}/${result.appName}.
|
|
5578
|
+
(0, output_1.printSuccess)(`Task upload preflight passed for ${result.creatorUsername}/${result.appName}. Upload can start.`);
|
|
5571
5579
|
return;
|
|
5572
5580
|
}
|
|
5573
5581
|
if ((0, node_fs_1.existsSync)(workerTaskUploadResultPath(workspaceDir))) {
|
package/dist/index.js
CHANGED
|
@@ -273,7 +273,7 @@ task
|
|
|
273
273
|
task
|
|
274
274
|
.command('upload')
|
|
275
275
|
.description('Upload the active agent task project as a private draft')
|
|
276
|
-
.option('--preflight-only', 'Run non-mutating
|
|
276
|
+
.option('--preflight-only', 'Run non-mutating checks without uploading')
|
|
277
277
|
.option('--env <env>', 'Environment override')
|
|
278
278
|
.action(async (opts) => {
|
|
279
279
|
await (0, worker_1.uploadTask)(opts);
|
|
@@ -1,35 +1,12 @@
|
|
|
1
|
-
import type { RecordAppUploadMediaCaptureRequest } from '@playdrop/types';
|
|
2
|
-
import type { AppTask } from './catalogue';
|
|
3
|
-
export type ListingMediaFile = {
|
|
4
|
-
fileKey: string;
|
|
5
|
-
sha256: string;
|
|
6
|
-
};
|
|
7
1
|
export type WorkerUploadPreflightContext = {
|
|
8
2
|
kind: 'NEW_GAME' | 'REMIX_GAME' | 'GAME_UPDATE';
|
|
9
3
|
target: 'FIRST_PARTY' | 'PERSONAL';
|
|
10
4
|
creatorUsername: string;
|
|
11
5
|
creatorRequest: string;
|
|
6
|
+
outputVersion?: string;
|
|
12
7
|
tweaks?: {
|
|
13
8
|
id: string;
|
|
14
9
|
values: Record<string, string | number | boolean>;
|
|
15
10
|
};
|
|
16
11
|
};
|
|
17
|
-
export declare function readMediaCaptureProof(input: {
|
|
18
|
-
task: AppTask;
|
|
19
|
-
preparedSessionFiles: ListingMediaFile[];
|
|
20
|
-
expectedRuntimeBundleHash?: string;
|
|
21
|
-
}): RecordAppUploadMediaCaptureRequest;
|
|
22
12
|
export declare function readWorkerUploadPreflightContext(projectDir: string): WorkerUploadPreflightContext | null;
|
|
23
|
-
export declare function assertAgentGameHeroListingPreflight(task: AppTask): void;
|
|
24
|
-
export declare function assertAgentGameIconListingPreflight(task: AppTask): void;
|
|
25
|
-
export declare function assertAgentGameVideoListingPreflight(task: AppTask): void;
|
|
26
|
-
export declare function assertAgentGamePreviewListingPreflight(task: AppTask): void;
|
|
27
|
-
export declare function assertAgentGameScreenshotListingPreflight(task: AppTask): void;
|
|
28
|
-
export declare function assertAgentGameCaptureReportPreflight(task: AppTask, options: {
|
|
29
|
-
requireCaptureReport: boolean;
|
|
30
|
-
expectedRuntimeBundleHash?: string;
|
|
31
|
-
}): void;
|
|
32
|
-
export declare function assertAgentGameListingPreflight(task: AppTask, options: {
|
|
33
|
-
requireCaptureReport: boolean;
|
|
34
|
-
}): void;
|
|
35
|
-
export declare function assertProjectListingPreflight(task: AppTask): void;
|