@playdrop/playdrop-cli 0.18.8 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/config/client-meta.json +2 -2
- package/dist/apps/upload.d.ts +2 -0
- package/dist/apps/upload.js +146 -60
- package/dist/catalogue.d.ts +18 -0
- package/dist/catalogue.js +171 -56
- package/dist/commands/devServer.js +3 -0
- package/dist/commands/validate.js +1 -0
- package/dist/commands/worker/game-source-git.js +7 -0
- package/dist/commands/worker/generation.d.ts +16 -1
- package/dist/commands/worker/generation.js +8 -2
- package/dist/commands/worker/ugc-processing.d.ts +13 -0
- package/dist/commands/worker/ugc-processing.js +146 -0
- package/dist/commands/worker.d.ts +27 -0
- package/dist/commands/worker.js +127 -38
- package/dist/proxyFetch.d.ts +5 -0
- package/dist/proxyFetch.js +10 -35
- package/dist/uploadDispatchers.d.ts +3 -0
- package/dist/uploadDispatchers.js +10 -0
- package/node_modules/@playdrop/api-client/dist/acquisition.d.ts +3 -1
- package/node_modules/@playdrop/api-client/dist/acquisition.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/acquisition.js +2 -2
- package/node_modules/@playdrop/api-client/dist/chat.d.ts +13 -4
- package/node_modules/@playdrop/api-client/dist/chat.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/client.d.ts +31 -10
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/core/request.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/core/request.js +11 -1
- package/node_modules/@playdrop/api-client/dist/domains/chat.d.ts +30 -9
- package/node_modules/@playdrop/api-client/dist/domains/chat.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/chat.js +24 -19
- package/node_modules/@playdrop/api-client/dist/domains/comments.d.ts +3 -1
- package/node_modules/@playdrop/api-client/dist/domains/comments.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/comments.js +2 -2
- package/node_modules/@playdrop/api-client/dist/index.d.ts +17 -6
- package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.js +12 -10
- package/node_modules/@playdrop/api-client/dist/runtime.d.ts +3 -0
- package/node_modules/@playdrop/api-client/dist/runtime.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/runtime.js +10 -1
- package/node_modules/@playdrop/config/client-meta.json +2 -2
- package/node_modules/@playdrop/game-source-git/dist/src/repository.d.ts +8 -0
- package/node_modules/@playdrop/game-source-git/dist/src/repository.d.ts.map +1 -1
- package/node_modules/@playdrop/game-source-git/dist/src/repository.js +30 -17
- package/node_modules/@playdrop/game-source-git/dist/test/core.test.js +10 -0
- package/node_modules/@playdrop/game-source-git/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@playdrop/game-source-git/package.json +2 -1
- package/node_modules/@playdrop/types/dist/agent-task-terminal.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/agent-task-terminal.js +1 -1
- package/node_modules/@playdrop/types/dist/api.d.ts +30 -3
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/api.js +1 -0
- package/node_modules/@playdrop/types/dist/app-listing-localization.d.ts +34 -0
- package/node_modules/@playdrop/types/dist/app-listing-localization.d.ts.map +1 -0
- package/node_modules/@playdrop/types/dist/app-listing-localization.js +146 -0
- package/node_modules/@playdrop/types/dist/chat.d.ts +7 -2
- package/node_modules/@playdrop/types/dist/chat.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/index.d.ts +3 -0
- package/node_modules/@playdrop/types/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/index.js +6 -0
- package/node_modules/@playdrop/types/dist/ugc-processing.d.ts +211 -0
- package/node_modules/@playdrop/types/dist/ugc-processing.d.ts.map +1 -0
- package/node_modules/@playdrop/types/dist/ugc-processing.js +144 -0
- package/node_modules/@playdrop/types/dist/ugc.d.ts +39 -0
- package/node_modules/@playdrop/types/dist/ugc.d.ts.map +1 -0
- package/node_modules/@playdrop/types/dist/ugc.js +70 -0
- package/node_modules/@playdrop/types/dist/version.d.ts +4 -0
- package/node_modules/@playdrop/types/dist/version.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/catalogue.js
CHANGED
|
@@ -9,7 +9,11 @@ exports.resolveWorkspaceApp = resolveWorkspaceApp;
|
|
|
9
9
|
exports.formatMetadataWarnings = formatMetadataWarnings;
|
|
10
10
|
exports.formatMissingMetadataWarnings = formatMissingMetadataWarnings;
|
|
11
11
|
exports.findAppTaskByFile = findAppTaskByFile;
|
|
12
|
+
exports.catalogueListingContent = catalogueListingContent;
|
|
13
|
+
exports.calculateCatalogueListingSourceHash = calculateCatalogueListingSourceHash;
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
12
15
|
const types_1 = require("@playdrop/types");
|
|
16
|
+
const types_2 = require("@playdrop/types");
|
|
13
17
|
const node_fs_1 = require("node:fs");
|
|
14
18
|
const node_path_1 = require("node:path");
|
|
15
19
|
const assetSpecs_1 = require("./assetSpecs");
|
|
@@ -17,7 +21,7 @@ const catalogue_utils_1 = require("./catalogue-utils");
|
|
|
17
21
|
const HEX_COLOR_REGEX = /^#?(?:[0-9a-fA-F]{6})$/;
|
|
18
22
|
const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
19
23
|
const LEGACY_CATALOGUE_VERSION_KEY = ["schema", "Version"].join("");
|
|
20
|
-
const ASSET_CATEGORY_SET = new Set(
|
|
24
|
+
const ASSET_CATEGORY_SET = new Set(types_2.ASSET_CATEGORY_VALUES);
|
|
21
25
|
const LISTING_IMAGE_EXTENSIONS = new Set([".png"]);
|
|
22
26
|
const LISTING_VIDEO_EXTENSIONS = new Set([".mp4"]);
|
|
23
27
|
exports.APP_DESCRIPTION_RECOMMENDED_MIN_CHARACTERS = 120;
|
|
@@ -26,7 +30,7 @@ exports.APP_RELEASE_NOTES_MAX_CHARACTERS = 240;
|
|
|
26
30
|
const MAX_CONTENT_TAGS_PER_ITEM = 20;
|
|
27
31
|
const APP_ALLOWED_LICENSES = new Set(["CLOSED", "PLAYDROP", "MIT"]);
|
|
28
32
|
const ASSET_ALLOWED_LICENSES = new Set(["CLOSED", "PLAYDROP", "MIT", "CC0"]);
|
|
29
|
-
const ASSET_SUBCATEGORY_SET_BY_CATEGORY =
|
|
33
|
+
const ASSET_SUBCATEGORY_SET_BY_CATEGORY = types_2.ASSET_SUBCATEGORY_DEFINITIONS.reduce((acc, definition) => {
|
|
30
34
|
if (!acc[definition.category]) {
|
|
31
35
|
acc[definition.category] = new Set();
|
|
32
36
|
}
|
|
@@ -240,7 +244,7 @@ function normalizeCatalogueRemixRef(value, expectedKind, errors, context) {
|
|
|
240
244
|
errors.push(`${context} remix must be a canonical ${expectedKind} version ref string.`);
|
|
241
245
|
return undefined;
|
|
242
246
|
}
|
|
243
|
-
const parsed = (0,
|
|
247
|
+
const parsed = (0, types_2.parseContentVersionRef)(trimmed);
|
|
244
248
|
if (!parsed) {
|
|
245
249
|
errors.push(`${context} remix must use canonical version ref format.`);
|
|
246
250
|
return undefined;
|
|
@@ -249,7 +253,7 @@ function normalizeCatalogueRemixRef(value, expectedKind, errors, context) {
|
|
|
249
253
|
errors.push(`${context} remix must point to a ${expectedKind} version.`);
|
|
250
254
|
return undefined;
|
|
251
255
|
}
|
|
252
|
-
return (0,
|
|
256
|
+
return (0, types_2.formatContentVersionRef)(parsed);
|
|
253
257
|
}
|
|
254
258
|
function normalizeCatalogueRelations(value, errors, context) {
|
|
255
259
|
if (!Array.isArray(value)) {
|
|
@@ -291,12 +295,12 @@ function normalizeCatalogueAppDependencyAssets(value, errors, context) {
|
|
|
291
295
|
errors.push(`${context} uses.assets[${index}] must be a non-empty asset ref string or { ref, runtimeKey } object.`);
|
|
292
296
|
continue;
|
|
293
297
|
}
|
|
294
|
-
const parsed = (0,
|
|
298
|
+
const parsed = (0, types_2.parseContentVersionRef)(ref);
|
|
295
299
|
if (!parsed || parsed.kind !== "asset") {
|
|
296
300
|
errors.push(`${context} uses.assets[${index}] must be a canonical asset version ref.`);
|
|
297
301
|
continue;
|
|
298
302
|
}
|
|
299
|
-
const normalizedRef = (0,
|
|
303
|
+
const normalizedRef = (0, types_2.formatContentVersionRef)(parsed);
|
|
300
304
|
if (seenRefs.has(normalizedRef)) {
|
|
301
305
|
errors.push(`${context} uses.assets contains duplicate ref "${normalizedRef}".`);
|
|
302
306
|
continue;
|
|
@@ -335,12 +339,12 @@ function normalizeCatalogueAppDependencyPacks(value, errors, context) {
|
|
|
335
339
|
errors.push(`${context} uses.packs[${index}] must be a non-empty pack version ref string. Use "pack:playdrop/name@version", not { ref, runtimeKey }.`);
|
|
336
340
|
continue;
|
|
337
341
|
}
|
|
338
|
-
const parsed = (0,
|
|
342
|
+
const parsed = (0, types_2.parseContentVersionRef)(entry.trim());
|
|
339
343
|
if (!parsed || parsed.kind !== "pack") {
|
|
340
344
|
errors.push(`${context} uses.packs[${index}] must be a canonical pack version ref.`);
|
|
341
345
|
continue;
|
|
342
346
|
}
|
|
343
|
-
const normalizedRef = (0,
|
|
347
|
+
const normalizedRef = (0, types_2.formatContentVersionRef)(parsed);
|
|
344
348
|
if (seenRefs.has(normalizedRef)) {
|
|
345
349
|
errors.push(`${context} uses.packs contains duplicate ref "${normalizedRef}".`);
|
|
346
350
|
continue;
|
|
@@ -375,7 +379,7 @@ function normalizeCatalogueTags(value, errors, context) {
|
|
|
375
379
|
}
|
|
376
380
|
let normalizedRef = "";
|
|
377
381
|
try {
|
|
378
|
-
normalizedRef = (0,
|
|
382
|
+
normalizedRef = (0, types_2.normalizeTagRef)(entry);
|
|
379
383
|
}
|
|
380
384
|
catch {
|
|
381
385
|
errors.push(`${context} tags[${index}] must use group-slug/tag-slug format.`);
|
|
@@ -406,8 +410,8 @@ function normalizeCatalogueAllowedTargetKinds(value, errors, context) {
|
|
|
406
410
|
for (let index = 0; index < value.length; index += 1) {
|
|
407
411
|
const entry = value[index];
|
|
408
412
|
const normalizedKind = typeof entry === "string" ? entry.trim().toUpperCase() : "";
|
|
409
|
-
if (!
|
|
410
|
-
errors.push(`${context} allowedTargetKinds[${index}] must be one of ${
|
|
413
|
+
if (!types_2.SAVED_ITEM_KIND_VALUES.includes(normalizedKind)) {
|
|
414
|
+
errors.push(`${context} allowedTargetKinds[${index}] must be one of ${types_2.SAVED_ITEM_KIND_VALUES.join(", ")}.`);
|
|
411
415
|
continue;
|
|
412
416
|
}
|
|
413
417
|
const savedItemKind = normalizedKind;
|
|
@@ -626,11 +630,11 @@ function normalizeAssetVisibilityValue(raw, errors, label) {
|
|
|
626
630
|
}
|
|
627
631
|
return normalized;
|
|
628
632
|
}
|
|
629
|
-
function normalizeContentLicenseValue(raw, errors, label, allowedValues, defaultValue =
|
|
633
|
+
function normalizeContentLicenseValue(raw, errors, label, allowedValues, defaultValue = types_2.DEFAULT_CONTENT_LICENSE) {
|
|
630
634
|
if (raw === undefined || raw === null || (typeof raw === "string" && raw.trim().length === 0)) {
|
|
631
635
|
return defaultValue;
|
|
632
636
|
}
|
|
633
|
-
const parsed = (0,
|
|
637
|
+
const parsed = (0, types_2.parseContentLicense)(raw);
|
|
634
638
|
if (!parsed || !allowedValues.has(parsed)) {
|
|
635
639
|
errors.push(`[${label}] license must be one of ${Array.from(allowedValues).join(", ")}.`);
|
|
636
640
|
return null;
|
|
@@ -670,8 +674,8 @@ function normalizeAssetSubcategoryValue(raw, category, errors, label) {
|
|
|
670
674
|
errors.push(`${label} must define subcategory.`);
|
|
671
675
|
return null;
|
|
672
676
|
}
|
|
673
|
-
const normalized = (0,
|
|
674
|
-
if (!(0,
|
|
677
|
+
const normalized = (0, types_2.normalizeAssetSubcategory)(raw);
|
|
678
|
+
if (!(0, types_2.isValidAssetSubcategorySlug)(normalized)) {
|
|
675
679
|
errors.push(`${label} uses invalid subcategory "${raw}".`);
|
|
676
680
|
return null;
|
|
677
681
|
}
|
|
@@ -740,7 +744,7 @@ function validateAchievementDefinitions(value, catalogueDir, errors) {
|
|
|
740
744
|
return;
|
|
741
745
|
}
|
|
742
746
|
const key = typeof entry.key === "string" ? entry.key.trim() : "";
|
|
743
|
-
if (!(0,
|
|
747
|
+
if (!(0, types_2.isPlayerMetaKey)(key)) {
|
|
744
748
|
errors.push(`achievements[${index}].key must match the player meta key format`);
|
|
745
749
|
return;
|
|
746
750
|
}
|
|
@@ -759,15 +763,15 @@ function validateAchievementDefinitions(value, catalogueDir, errors) {
|
|
|
759
763
|
errors.push(`achievements[${index}].description must be a non-empty string`);
|
|
760
764
|
return;
|
|
761
765
|
}
|
|
762
|
-
const kind = (0,
|
|
766
|
+
const kind = (0, types_2.parseAppAchievementKind)(entry.kind);
|
|
763
767
|
if (!kind) {
|
|
764
|
-
errors.push(`achievements[${index}].kind must be one of ${
|
|
768
|
+
errors.push(`achievements[${index}].kind must be one of ${types_2.APP_ACHIEVEMENT_KIND_VALUES.join(", ")}`);
|
|
765
769
|
return;
|
|
766
770
|
}
|
|
767
771
|
const hidden = Boolean(entry.hidden);
|
|
768
|
-
const status = (0,
|
|
772
|
+
const status = (0, types_2.parsePlayerMetaDefinitionStatus)(entry.status ?? "ACTIVE");
|
|
769
773
|
if (!status) {
|
|
770
|
-
errors.push(`achievements[${index}].status must be one of ${
|
|
774
|
+
errors.push(`achievements[${index}].status must be one of ${types_2.PLAYER_META_DEFINITION_STATUS_VALUES.join(", ")}`);
|
|
771
775
|
return;
|
|
772
776
|
}
|
|
773
777
|
const icon = typeof entry.icon === "string" ? entry.icon.trim() : "";
|
|
@@ -828,7 +832,7 @@ function validateLeaderboardDefinitions(value, errors) {
|
|
|
828
832
|
return;
|
|
829
833
|
}
|
|
830
834
|
const key = typeof entry.key === "string" ? entry.key.trim() : "";
|
|
831
|
-
if (!(0,
|
|
835
|
+
if (!(0, types_2.isPlayerMetaKey)(key)) {
|
|
832
836
|
errors.push(`leaderboards[${index}].key must match the player meta key format`);
|
|
833
837
|
return;
|
|
834
838
|
}
|
|
@@ -847,23 +851,23 @@ function validateLeaderboardDefinitions(value, errors) {
|
|
|
847
851
|
errors.push(`leaderboards[${index}].description must be a non-empty string`);
|
|
848
852
|
return;
|
|
849
853
|
}
|
|
850
|
-
const scoreType = (0,
|
|
854
|
+
const scoreType = (0, types_2.parseAppLeaderboardScoreType)(entry.scoreType);
|
|
851
855
|
if (!scoreType) {
|
|
852
|
-
errors.push(`leaderboards[${index}].scoreType must be one of ${
|
|
856
|
+
errors.push(`leaderboards[${index}].scoreType must be one of ${types_2.APP_LEADERBOARD_SCORE_TYPE_VALUES.join(", ")}`);
|
|
853
857
|
return;
|
|
854
858
|
}
|
|
855
|
-
const sort = (0,
|
|
859
|
+
const sort = (0, types_2.parseAppLeaderboardSort)(entry.sort);
|
|
856
860
|
if (!sort) {
|
|
857
|
-
errors.push(`leaderboards[${index}].sort must be one of ${
|
|
861
|
+
errors.push(`leaderboards[${index}].sort must be one of ${types_2.APP_LEADERBOARD_SORT_VALUES.join(", ")}`);
|
|
858
862
|
return;
|
|
859
863
|
}
|
|
860
|
-
if (!(0,
|
|
864
|
+
if (!(0, types_2.isValidLeaderboardDefinitionCombination)(scoreType, sort)) {
|
|
861
865
|
errors.push(`leaderboards[${index}] must use INTEGER + DESC or TIME_MS + ASC`);
|
|
862
866
|
return;
|
|
863
867
|
}
|
|
864
|
-
const status = (0,
|
|
868
|
+
const status = (0, types_2.parsePlayerMetaDefinitionStatus)(entry.status ?? "ACTIVE");
|
|
865
869
|
if (!status) {
|
|
866
|
-
errors.push(`leaderboards[${index}].status must be one of ${
|
|
870
|
+
errors.push(`leaderboards[${index}].status must be one of ${types_2.PLAYER_META_DEFINITION_STATUS_VALUES.join(", ")}`);
|
|
867
871
|
return;
|
|
868
872
|
}
|
|
869
873
|
const unitLabel = typeof entry.unitLabel === "string" && entry.unitLabel.trim().length > 0
|
|
@@ -892,9 +896,9 @@ function validateAppMetadata(entry) {
|
|
|
892
896
|
const color = validateOptionalColor(entry.color, Object.prototype.hasOwnProperty.call(entry, "color"), errors);
|
|
893
897
|
let type;
|
|
894
898
|
if (typeof entry.type === "string" && entry.type.trim()) {
|
|
895
|
-
const parsedType = (0,
|
|
899
|
+
const parsedType = (0, types_2.parseAppType)(entry.type.trim());
|
|
896
900
|
if (!parsedType) {
|
|
897
|
-
errors.push(`type must be one of ${
|
|
901
|
+
errors.push(`type must be one of ${types_2.APP_TYPE_VALUES.join(", ")}`);
|
|
898
902
|
}
|
|
899
903
|
else {
|
|
900
904
|
type = parsedType;
|
|
@@ -909,8 +913,8 @@ function validateAppMetadata(entry) {
|
|
|
909
913
|
if (typeof entry.subtitle !== "string" || entry.subtitle.trim().length === 0) {
|
|
910
914
|
errors.push("subtitle must be a non-empty string when provided");
|
|
911
915
|
}
|
|
912
|
-
else if (entry.subtitle.trim().length >
|
|
913
|
-
errors.push(`subtitle must be ${
|
|
916
|
+
else if (entry.subtitle.trim().length > types_2.APP_SUBTITLE_MAX_LENGTH) {
|
|
917
|
+
errors.push(`subtitle must be ${types_2.APP_SUBTITLE_MAX_LENGTH} characters or fewer`);
|
|
914
918
|
}
|
|
915
919
|
else {
|
|
916
920
|
subtitle = entry.subtitle.trim();
|
|
@@ -951,7 +955,7 @@ function validateAppMetadata(entry) {
|
|
|
951
955
|
}
|
|
952
956
|
let primarySurface;
|
|
953
957
|
if (Object.prototype.hasOwnProperty.call(entry, "primarySurface")) {
|
|
954
|
-
primarySurface = (0,
|
|
958
|
+
primarySurface = (0, types_2.parseAppSurface)(entry.primarySurface) ?? undefined;
|
|
955
959
|
if (!primarySurface) {
|
|
956
960
|
errors.push("primarySurface must be DESKTOP, MOBILE_LANDSCAPE, or MOBILE_PORTRAIT");
|
|
957
961
|
}
|
|
@@ -961,7 +965,7 @@ function validateAppMetadata(entry) {
|
|
|
961
965
|
}
|
|
962
966
|
let playtestTapes;
|
|
963
967
|
if (Object.prototype.hasOwnProperty.call(entry, "playtestTapes")) {
|
|
964
|
-
const normalized = (0,
|
|
968
|
+
const normalized = (0, types_2.normalizeAppPlaytestTapes)(entry.playtestTapes, {
|
|
965
969
|
surfaceTargets: surfaceTargetsList,
|
|
966
970
|
requireComplete: true,
|
|
967
971
|
});
|
|
@@ -1168,8 +1172,8 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1168
1172
|
let versionVisibility;
|
|
1169
1173
|
const rawVisibility = typeof entry.visibility === "string" ? entry.visibility.trim().toUpperCase() : "";
|
|
1170
1174
|
if (rawVisibility) {
|
|
1171
|
-
if (!
|
|
1172
|
-
errors.push(`[${label}] Skipping ${rawName}: visibility must be one of ${
|
|
1175
|
+
if (!types_2.APP_VERSION_VISIBILITY_VALUES.includes(rawVisibility)) {
|
|
1176
|
+
errors.push(`[${label}] Skipping ${rawName}: visibility must be one of ${types_2.APP_VERSION_VISIBILITY_VALUES.join(", ")}.`);
|
|
1173
1177
|
continue;
|
|
1174
1178
|
}
|
|
1175
1179
|
versionVisibility = rawVisibility;
|
|
@@ -1177,8 +1181,8 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1177
1181
|
let hostingMode;
|
|
1178
1182
|
const rawHostingMode = typeof entry.hostingMode === "string" ? entry.hostingMode.trim().toUpperCase() : "";
|
|
1179
1183
|
if (rawHostingMode) {
|
|
1180
|
-
if (!
|
|
1181
|
-
errors.push(`[${label}] Skipping ${rawName}: hostingMode must be one of ${
|
|
1184
|
+
if (!types_2.APP_HOSTING_MODE_VALUES.includes(rawHostingMode)) {
|
|
1185
|
+
errors.push(`[${label}] Skipping ${rawName}: hostingMode must be one of ${types_2.APP_HOSTING_MODE_VALUES.join(", ")}.`);
|
|
1182
1186
|
continue;
|
|
1183
1187
|
}
|
|
1184
1188
|
hostingMode = rawHostingMode;
|
|
@@ -1186,8 +1190,8 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1186
1190
|
let authMode;
|
|
1187
1191
|
const rawAuthMode = typeof entry.authMode === "string" ? entry.authMode.trim().toUpperCase() : "";
|
|
1188
1192
|
if (rawAuthMode) {
|
|
1189
|
-
if (!
|
|
1190
|
-
errors.push(`[${label}] Skipping ${rawName}: authMode must be one of ${
|
|
1193
|
+
if (!types_2.APP_AUTH_MODE_VALUES.includes(rawAuthMode)) {
|
|
1194
|
+
errors.push(`[${label}] Skipping ${rawName}: authMode must be one of ${types_2.APP_AUTH_MODE_VALUES.join(", ")}.`);
|
|
1191
1195
|
continue;
|
|
1192
1196
|
}
|
|
1193
1197
|
authMode = rawAuthMode;
|
|
@@ -1245,8 +1249,8 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1245
1249
|
let controllerMode;
|
|
1246
1250
|
const rawControllerMode = typeof entry.controllerMode === "string" ? entry.controllerMode.trim().toUpperCase() : "";
|
|
1247
1251
|
if (rawControllerMode) {
|
|
1248
|
-
if (!
|
|
1249
|
-
errors.push(`[${label}] Skipping ${rawName}: controllerMode must be one of ${
|
|
1252
|
+
if (!types_2.APP_CONTROLLER_MODE_VALUES.includes(rawControllerMode)) {
|
|
1253
|
+
errors.push(`[${label}] Skipping ${rawName}: controllerMode must be one of ${types_2.APP_CONTROLLER_MODE_VALUES.join(", ")}.`);
|
|
1250
1254
|
continue;
|
|
1251
1255
|
}
|
|
1252
1256
|
controllerMode = rawControllerMode;
|
|
@@ -1293,7 +1297,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1293
1297
|
errors.push(`[${label}] Skipping ${rawName}: editorSupported can only be true for HOSTED apps.`);
|
|
1294
1298
|
continue;
|
|
1295
1299
|
}
|
|
1296
|
-
const defaultLicense = (hostingMode ?? "HOSTED") === "EXTERNAL" ? "CLOSED" :
|
|
1300
|
+
const defaultLicense = (hostingMode ?? "HOSTED") === "EXTERNAL" ? "CLOSED" : types_2.DEFAULT_CONTENT_LICENSE;
|
|
1297
1301
|
const license = normalizeContentLicenseValue(entry.license, errors, `${label} app "${rawName}"`, APP_ALLOWED_LICENSES, defaultLicense);
|
|
1298
1302
|
if (!license) {
|
|
1299
1303
|
continue;
|
|
@@ -1382,6 +1386,22 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1382
1386
|
}
|
|
1383
1387
|
}
|
|
1384
1388
|
}
|
|
1389
|
+
if (rawListing.socialLandscape !== undefined) {
|
|
1390
|
+
const socialPath = rawListing.socialLandscape;
|
|
1391
|
+
if (typeof socialPath !== "string" || !socialPath.trim()) {
|
|
1392
|
+
errors.push(`[${label}] invalid listing.socialLandscape`);
|
|
1393
|
+
listingValidationFailed = true;
|
|
1394
|
+
}
|
|
1395
|
+
else {
|
|
1396
|
+
const failure = ([".jpg", ".jpeg"].includes((0, node_path_1.extname)(socialPath).toLowerCase()) ? undefined : validateListingAssetExtension(socialPath, "listing.socialLandscape", "image")) ?? validateListingAssetPath(file.directory, socialPath, "listing.socialLandscape");
|
|
1397
|
+
if (failure) {
|
|
1398
|
+
errors.push(failure);
|
|
1399
|
+
listingValidationFailed = true;
|
|
1400
|
+
}
|
|
1401
|
+
else
|
|
1402
|
+
resolvedListing.socialLandscapePath = resolveListingAssetPath(file.directory, socialPath);
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1385
1405
|
for (const mediaField of [
|
|
1386
1406
|
{
|
|
1387
1407
|
value: rawListing.screenshotsPortrait,
|
|
@@ -1461,7 +1481,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1461
1481
|
}
|
|
1462
1482
|
let design;
|
|
1463
1483
|
if (Object.prototype.hasOwnProperty.call(entry, "design")) {
|
|
1464
|
-
const parsedDesign = (0,
|
|
1484
|
+
const parsedDesign = (0, types_2.normalizeAppVersionDesign)(entry.design);
|
|
1465
1485
|
if (!parsedDesign.ok) {
|
|
1466
1486
|
errors.push(`[${label}] App "${rawName}" ${parsedDesign.error}`);
|
|
1467
1487
|
continue;
|
|
@@ -1470,7 +1490,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1470
1490
|
}
|
|
1471
1491
|
let players;
|
|
1472
1492
|
if (Object.prototype.hasOwnProperty.call(entry, "players")) {
|
|
1473
|
-
const parsedPlayers = (0,
|
|
1493
|
+
const parsedPlayers = (0, types_2.normalizeAppPlayers)(entry.players);
|
|
1474
1494
|
if (!parsedPlayers.ok) {
|
|
1475
1495
|
errors.push(`[${label}] App "${rawName}" ${parsedPlayers.error}`);
|
|
1476
1496
|
continue;
|
|
@@ -1496,7 +1516,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1496
1516
|
}
|
|
1497
1517
|
let creation;
|
|
1498
1518
|
if (Object.prototype.hasOwnProperty.call(entry, "creation")) {
|
|
1499
|
-
const parsedCreation = (0,
|
|
1519
|
+
const parsedCreation = (0, types_2.normalizeAppCreationMetadata)(entry.creation);
|
|
1500
1520
|
if (!parsedCreation.ok) {
|
|
1501
1521
|
errors.push(`[${label}] App "${rawName}" ${parsedCreation.error}`);
|
|
1502
1522
|
continue;
|
|
@@ -1524,7 +1544,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1524
1544
|
}
|
|
1525
1545
|
let tweaks;
|
|
1526
1546
|
if (Object.prototype.hasOwnProperty.call(entry, "tweaks")) {
|
|
1527
|
-
const parsedTweaks = (0,
|
|
1547
|
+
const parsedTweaks = (0, types_2.normalizeAppTweaks)(entry.tweaks);
|
|
1528
1548
|
if (!parsedTweaks.ok) {
|
|
1529
1549
|
errors.push(`[${label}] App "${rawName}" ${parsedTweaks.error}`);
|
|
1530
1550
|
continue;
|
|
@@ -1695,8 +1715,89 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1695
1715
|
if (errors.length > runtimeValidationErrorCount) {
|
|
1696
1716
|
continue;
|
|
1697
1717
|
}
|
|
1718
|
+
let listingLocalizations = [];
|
|
1719
|
+
let sourceLocale = null;
|
|
1720
|
+
let listingSourceHash;
|
|
1721
|
+
try {
|
|
1722
|
+
sourceLocale = (0, types_1.normalizeAppListingSourceLocale)(entry.sourceLocale);
|
|
1723
|
+
const rawLocalizations = entry.listingLocalizations;
|
|
1724
|
+
if (rawLocalizations !== undefined && (!rawLocalizations || typeof rawLocalizations !== "object" || Array.isArray(rawLocalizations)))
|
|
1725
|
+
throw new Error("invalid_listing_localizations");
|
|
1726
|
+
for (const [locale, value] of Object.entries(rawLocalizations ?? {})) {
|
|
1727
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1728
|
+
throw new Error("invalid_listing_localization");
|
|
1729
|
+
const localized = value;
|
|
1730
|
+
const allowedFields = new Set(["displayName", "subtitle", "description", "controls", "makingOf", "releaseNotes", "sourceHash", "listing"]);
|
|
1731
|
+
const unsupported = Object.keys(localized).filter((key) => !allowedFields.has(key));
|
|
1732
|
+
if (unsupported.length)
|
|
1733
|
+
throw new Error(`unsupported_listing_localization_fields:${locale}:${unsupported.join(",")}`);
|
|
1734
|
+
(0, types_1.normalizeAppListingLocalizations)([{ ...localized, locale }], sourceLocale);
|
|
1735
|
+
const media = localized.listing ?? {};
|
|
1736
|
+
if (!media || typeof media !== "object" || Array.isArray(media))
|
|
1737
|
+
throw new Error("invalid_listing_media");
|
|
1738
|
+
const allowedMedia = new Set([...types_1.APP_LISTING_PATH_FIELDS.map((field) => field.replace(/Path$/, "")), ...types_1.APP_LISTING_ARRAY_FIELDS]);
|
|
1739
|
+
const unsupportedMedia = Object.keys(media).filter((key) => !allowedMedia.has(key));
|
|
1740
|
+
if (unsupportedMedia.length)
|
|
1741
|
+
throw new Error(`unsupported_listing_localization_media_fields:${locale}:${unsupportedMedia.join(",")}`);
|
|
1742
|
+
for (const field of types_1.APP_LISTING_ARRAY_FIELDS) {
|
|
1743
|
+
const entries = media[field];
|
|
1744
|
+
if (entries === undefined)
|
|
1745
|
+
continue;
|
|
1746
|
+
if (!Array.isArray(entries))
|
|
1747
|
+
throw new Error(`invalid_listing_${field}`);
|
|
1748
|
+
for (const entry of entries) {
|
|
1749
|
+
if (entry && typeof entry === "object" && !Array.isArray(entry)) {
|
|
1750
|
+
const unsupported = Object.keys(entry).filter((key) => !["path", "slug", "title", "alt", "caption", "description"].includes(key));
|
|
1751
|
+
if (unsupported.length)
|
|
1752
|
+
throw new Error(`unsupported_listing_localization_media_fields:${locale}:${field}:${unsupported.join(",")}`);
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
if (options.listingAssets !== "ignore") {
|
|
1758
|
+
listingLocalizations = (0, types_1.normalizeAppListingLocalizations)(Object.entries(rawLocalizations ?? {}).map(([locale, value]) => {
|
|
1759
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
1760
|
+
throw new Error("invalid_listing_localization");
|
|
1761
|
+
const localized = value;
|
|
1762
|
+
const media = localized.listing ?? {};
|
|
1763
|
+
if (!media || typeof media !== "object" || Array.isArray(media))
|
|
1764
|
+
throw new Error("invalid_listing_media");
|
|
1765
|
+
const paths = {};
|
|
1766
|
+
const metadata = [];
|
|
1767
|
+
for (const field of types_1.APP_LISTING_PATH_FIELDS) {
|
|
1768
|
+
const key = field.replace(/Path$/, "");
|
|
1769
|
+
const value = media[key];
|
|
1770
|
+
if (value === undefined || value === null)
|
|
1771
|
+
continue;
|
|
1772
|
+
if (typeof value !== "string" || !value.trim())
|
|
1773
|
+
throw new Error(`invalid_listing_${key}`);
|
|
1774
|
+
const failure = (field === "socialLandscapePath" && [".jpg", ".jpeg"].includes((0, node_path_1.extname)(value).toLowerCase()) ? undefined : validateListingAssetExtension(value, `${locale}.listing.${key}`, "image")) ?? validateListingAssetPath(file.directory, value, `${locale}.listing.${key}`);
|
|
1775
|
+
if (failure)
|
|
1776
|
+
throw new Error(failure);
|
|
1777
|
+
paths[field] = resolveListingAssetPath(file.directory, value);
|
|
1778
|
+
}
|
|
1779
|
+
for (const field of types_1.APP_LISTING_ARRAY_FIELDS) {
|
|
1780
|
+
const resolved = resolveListingMediaEntries({ value: media[field], baseDir: file.directory, fieldName: `${locale}.listing.${field}`, kind: field.startsWith("videos") ? "video" : "image", fileKeyPrefix: field });
|
|
1781
|
+
if (resolved.error)
|
|
1782
|
+
throw new Error(resolved.error);
|
|
1783
|
+
paths[field] = resolved.paths;
|
|
1784
|
+
metadata.push(...resolved.metadata);
|
|
1785
|
+
}
|
|
1786
|
+
return { ...localized, ...paths, listingMedia: metadata, locale };
|
|
1787
|
+
}), sourceLocale);
|
|
1788
|
+
if (sourceLocale)
|
|
1789
|
+
listingSourceHash = calculateCatalogueListingSourceHash({ ...metadata, sourceLocale, listing, controls, makingOf, releaseNotes });
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
catch (error) {
|
|
1793
|
+
errors.push(`[${label}] ${rawName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1794
|
+
continue;
|
|
1795
|
+
}
|
|
1698
1796
|
tasks.push({
|
|
1699
1797
|
kind: "app",
|
|
1798
|
+
sourceLocale,
|
|
1799
|
+
listingSourceHash,
|
|
1800
|
+
listingLocalizations,
|
|
1700
1801
|
name: rawName,
|
|
1701
1802
|
cataloguePath: label,
|
|
1702
1803
|
catalogueAbsolutePath: file.absolutePath,
|
|
@@ -1820,8 +1921,8 @@ function buildAssetSpecTasks(catalogues) {
|
|
|
1820
1921
|
let validationKind = loadedContract.validationKind;
|
|
1821
1922
|
if (typeof entry.validationKind === "string" && entry.validationKind.trim().length > 0) {
|
|
1822
1923
|
const normalizedValidationKind = entry.validationKind.trim().toUpperCase();
|
|
1823
|
-
if (!
|
|
1824
|
-
errors.push(`[${label}] Asset spec "${name}@${version}" validationKind must be one of ${
|
|
1924
|
+
if (!types_2.ASSET_SPEC_VALIDATION_KIND_VALUES.includes(normalizedValidationKind)) {
|
|
1925
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" validationKind must be one of ${types_2.ASSET_SPEC_VALIDATION_KIND_VALUES.join(", ")}.`);
|
|
1825
1926
|
continue;
|
|
1826
1927
|
}
|
|
1827
1928
|
if (normalizedValidationKind !== loadedContract.validationKind) {
|
|
@@ -1833,8 +1934,8 @@ function buildAssetSpecTasks(catalogues) {
|
|
|
1833
1934
|
let status = "ACTIVE";
|
|
1834
1935
|
if (typeof entry.status === "string" && entry.status.trim().length > 0) {
|
|
1835
1936
|
const normalizedStatus = entry.status.trim().toUpperCase();
|
|
1836
|
-
if (!
|
|
1837
|
-
errors.push(`[${label}] Asset spec "${name}@${version}" status must be one of ${
|
|
1937
|
+
if (!types_2.ASSET_SPEC_STATUS_VALUES.includes(normalizedStatus)) {
|
|
1938
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" status must be one of ${types_2.ASSET_SPEC_STATUS_VALUES.join(", ")}.`);
|
|
1838
1939
|
continue;
|
|
1839
1940
|
}
|
|
1840
1941
|
status = normalizedStatus;
|
|
@@ -2012,7 +2113,7 @@ function buildAssetTasks(catalogues, assetSpecTasks) {
|
|
|
2012
2113
|
assetSpecContract = directAssetSpecTask.contract;
|
|
2013
2114
|
}
|
|
2014
2115
|
else {
|
|
2015
|
-
const parsedAssetSpec = (0,
|
|
2116
|
+
const parsedAssetSpec = (0, types_2.parseAssetSpecVersionRef)(assetSpec);
|
|
2016
2117
|
if (parsedAssetSpec) {
|
|
2017
2118
|
const fallbackAssetSpecTask = uniqueAssetSpecTaskByNameVersion.get(`${parsedAssetSpec.name}@${parsedAssetSpec.version}`);
|
|
2018
2119
|
if (fallbackAssetSpecTask) {
|
|
@@ -2194,8 +2295,8 @@ function buildAssetPackTasks(catalogues) {
|
|
|
2194
2295
|
let hostingMode;
|
|
2195
2296
|
const rawHostingMode = typeof entry.hostingMode === "string" ? entry.hostingMode.trim().toUpperCase() : "";
|
|
2196
2297
|
if (rawHostingMode) {
|
|
2197
|
-
if (!
|
|
2198
|
-
errors.push(`[${label}] Asset pack "${name}" hostingMode must be one of ${
|
|
2298
|
+
if (!types_2.APP_HOSTING_MODE_VALUES.includes(rawHostingMode)) {
|
|
2299
|
+
errors.push(`[${label}] Asset pack "${name}" hostingMode must be one of ${types_2.APP_HOSTING_MODE_VALUES.join(", ")}.`);
|
|
2199
2300
|
continue;
|
|
2200
2301
|
}
|
|
2201
2302
|
hostingMode = rawHostingMode;
|
|
@@ -2440,7 +2541,7 @@ function resolveCatalogueTagGroups(rootDir) {
|
|
|
2440
2541
|
continue;
|
|
2441
2542
|
}
|
|
2442
2543
|
const slug = typeof entry.slug === "string" ? entry.slug.trim().toLowerCase() : "";
|
|
2443
|
-
if (!slug || !(0,
|
|
2544
|
+
if (!slug || !(0, types_2.isValidTagSlug)(slug)) {
|
|
2444
2545
|
errors.push(`[${label}] tagGroups[${index}] slug must use lowercase slug format.`);
|
|
2445
2546
|
continue;
|
|
2446
2547
|
}
|
|
@@ -2468,7 +2569,7 @@ function resolveCatalogueTagGroups(rootDir) {
|
|
|
2468
2569
|
continue;
|
|
2469
2570
|
}
|
|
2470
2571
|
const tagSlug = typeof rawTag.slug === "string" ? rawTag.slug.trim().toLowerCase() : "";
|
|
2471
|
-
if (!tagSlug || !(0,
|
|
2572
|
+
if (!tagSlug || !(0, types_2.isValidTagSlug)(tagSlug)) {
|
|
2472
2573
|
errors.push(`[${label}] Tag group "${slug}" tags[${tagIndex}] slug must use lowercase slug format.`);
|
|
2473
2574
|
continue;
|
|
2474
2575
|
}
|
|
@@ -2705,3 +2806,17 @@ function findAppTaskByFile(htmlPath, options = {}) {
|
|
|
2705
2806
|
}
|
|
2706
2807
|
return { task: undefined, warnings: [], errors: [] };
|
|
2707
2808
|
}
|
|
2809
|
+
function catalogueListingContent(task) {
|
|
2810
|
+
const listing = task.listing;
|
|
2811
|
+
return (0, types_1.normalizeAppListingContent)({ ...task,
|
|
2812
|
+
iconPath: listing?.iconPath, heroPortraitPath: listing?.heroPortraitPath, heroLandscapePath: listing?.heroLandscapePath, socialLandscapePath: listing?.socialLandscapePath,
|
|
2813
|
+
screenshotsPortrait: listing?.screenshotPortraitPaths, screenshotsLandscape: listing?.screenshotLandscapePaths,
|
|
2814
|
+
videosPortrait: listing?.videoPortraitPaths, videosLandscape: listing?.videoLandscapePaths, listingMedia: listing?.mediaMetadata,
|
|
2815
|
+
});
|
|
2816
|
+
}
|
|
2817
|
+
function calculateCatalogueListingSourceHash(task) {
|
|
2818
|
+
const content = catalogueListingContent(task);
|
|
2819
|
+
const paths = [...types_1.APP_LISTING_PATH_FIELDS.flatMap((field) => content[field] ? [content[field]] : []), ...types_1.APP_LISTING_ARRAY_FIELDS.flatMap((field) => content[field])];
|
|
2820
|
+
const hashes = new Map(paths.map((file) => [file, (0, node_crypto_1.createHash)("sha256").update((0, node_fs_1.readFileSync)(file)).digest("hex")]));
|
|
2821
|
+
return (0, node_crypto_1.createHash)("sha256").update((0, types_1.canonicalAppListingSource)(content, task.sourceLocale ?? null, hashes)).digest("hex");
|
|
2822
|
+
}
|
|
@@ -545,6 +545,9 @@ async function ensureDevRouterRunning(port = exports.DEV_ROUTER_PORT) {
|
|
|
545
545
|
}
|
|
546
546
|
throw new Error(`dev_router_incompatible:port_${port}`);
|
|
547
547
|
}
|
|
548
|
+
if (process.env.PLAYDROP_WORKER_CONTEXT === "1") {
|
|
549
|
+
throw new Error(`worker_dev_router_missing:port_${port}`);
|
|
550
|
+
}
|
|
548
551
|
await startOwnedDevRouter(port);
|
|
549
552
|
}
|
|
550
553
|
// Managed Mac workers call this with their reserved slots before advertising
|
|
@@ -259,6 +259,7 @@ async function validate(pathOrName, options = {}) {
|
|
|
259
259
|
entityType: task.kind,
|
|
260
260
|
entityId,
|
|
261
261
|
catalogue: task.cataloguePath,
|
|
262
|
+
...(task.kind === "app" && task.listingSourceHash ? { detail: `listingSourceHash=${task.listingSourceHash}` } : {}),
|
|
262
263
|
};
|
|
263
264
|
results.push(entry);
|
|
264
265
|
console.log((0, uploadLog_1.formatTaskLogLine)(entry));
|
|
@@ -366,6 +366,13 @@ async function setupGameSourceWorkspace(input) {
|
|
|
366
366
|
repoPath: projectDir,
|
|
367
367
|
listing: {
|
|
368
368
|
version: source.listingSync.version,
|
|
369
|
+
sourceLocale: source.listingSync.sourceLocale,
|
|
370
|
+
listingSourceHash: source.listingSync.listingSourceHash,
|
|
371
|
+
listingLocalizations: source.listingSync.listingLocalizations,
|
|
372
|
+
listingMedia: source.listingSync.listingMedia,
|
|
373
|
+
controls: source.listingSync.controls,
|
|
374
|
+
makingOf: source.listingSync.makingOf,
|
|
375
|
+
releaseNotes: source.listingSync.releaseNotes,
|
|
369
376
|
displayName: source.listingSync.displayName,
|
|
370
377
|
subtitle: source.listingSync.subtitle,
|
|
371
378
|
description: source.listingSync.description,
|
|
@@ -55,13 +55,28 @@ export declare function triggerGenerationWorkerFailpoint(input: {
|
|
|
55
55
|
}): Promise<boolean>;
|
|
56
56
|
export declare function configureFalCredential(workerHomeDir: string): Promise<void>;
|
|
57
57
|
export declare function buildSandboxedCodexArgs(input: {
|
|
58
|
-
sandbox: "read-only" | "workspace-write";
|
|
58
|
+
sandbox: "read-only" | "workspace-write" | "danger-full-access";
|
|
59
59
|
outputPath: string;
|
|
60
60
|
prompt: string;
|
|
61
61
|
outputSchemaPath?: string;
|
|
62
62
|
persistSession?: boolean;
|
|
63
|
+
model?: string;
|
|
64
|
+
reasoningEffort?: string;
|
|
65
|
+
imagePaths?: string[];
|
|
63
66
|
}): string[];
|
|
64
67
|
export declare function retainScreeningTranscript(codexHomeDir: string, taskId: number): Promise<void>;
|
|
68
|
+
export declare function runCodex(input: {
|
|
69
|
+
cwd: string;
|
|
70
|
+
prompt: string;
|
|
71
|
+
sandbox: "read-only" | "workspace-write" | "danger-full-access";
|
|
72
|
+
outputPath: string;
|
|
73
|
+
outputSchema?: Record<string, unknown>;
|
|
74
|
+
signal: AbortSignal;
|
|
75
|
+
screeningTaskId?: number;
|
|
76
|
+
model?: string;
|
|
77
|
+
reasoningEffort?: string;
|
|
78
|
+
imagePaths?: string[];
|
|
79
|
+
}): Promise<void>;
|
|
65
80
|
export declare function falInput(request: CreateAiGenerationTaskRequest, resolvedInputs: Map<string, string>): Record<string, unknown>;
|
|
66
81
|
export declare function selectFalOutputs(kind: CreateAiGenerationTaskRequest["kind"], value: Record<string, unknown>): {
|
|
67
82
|
primary: FalFile;
|
|
@@ -49,6 +49,7 @@ exports.triggerGenerationWorkerFailpoint = triggerGenerationWorkerFailpoint;
|
|
|
49
49
|
exports.configureFalCredential = configureFalCredential;
|
|
50
50
|
exports.buildSandboxedCodexArgs = buildSandboxedCodexArgs;
|
|
51
51
|
exports.retainScreeningTranscript = retainScreeningTranscript;
|
|
52
|
+
exports.runCodex = runCodex;
|
|
52
53
|
exports.falInput = falInput;
|
|
53
54
|
exports.selectFalOutputs = selectFalOutputs;
|
|
54
55
|
exports.validatePrimary = validatePrimary;
|
|
@@ -400,10 +401,12 @@ function buildSandboxedCodexArgs(input) {
|
|
|
400
401
|
"--sandbox",
|
|
401
402
|
input.sandbox,
|
|
402
403
|
"--model",
|
|
403
|
-
CODEX_MODEL,
|
|
404
|
+
input.model ?? CODEX_MODEL,
|
|
404
405
|
"-c",
|
|
405
|
-
|
|
406
|
+
`model_reasoning_effort="${input.reasoningEffort ?? 'high'}"`,
|
|
406
407
|
];
|
|
408
|
+
for (const imagePath of input.imagePaths ?? [])
|
|
409
|
+
args.push('--image', imagePath);
|
|
407
410
|
if (input.outputSchemaPath)
|
|
408
411
|
args.push("--output-schema", input.outputSchemaPath);
|
|
409
412
|
args.push("-o", input.outputPath, input.prompt);
|
|
@@ -448,6 +451,9 @@ async function runCodex(input) {
|
|
|
448
451
|
prompt: input.prompt,
|
|
449
452
|
persistSession: input.screeningTaskId !== undefined,
|
|
450
453
|
...(outputSchemaPath ? { outputSchemaPath } : {}),
|
|
454
|
+
...(input.model ? { model: input.model } : {}),
|
|
455
|
+
...(input.reasoningEffort ? { reasoningEffort: input.reasoningEffort } : {}),
|
|
456
|
+
...(input.imagePaths ? { imagePaths: input.imagePaths } : {}),
|
|
451
457
|
});
|
|
452
458
|
const runtime = await prepareGenerationCodexRuntime();
|
|
453
459
|
try {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ApiClient } from '@playdrop/api-client';
|
|
2
|
+
import { type UgcProcessingResult, type WorkerUgcTaskAssignmentV5 } from '@playdrop/types';
|
|
3
|
+
export declare const UGC_PROCESSING_PROMPT: string;
|
|
4
|
+
export declare function normalizeWorkerUgcAssignment(value: unknown): WorkerUgcTaskAssignmentV5;
|
|
5
|
+
export declare function parseUgcModelOutput(text: string, claudeEnvelope?: boolean): {
|
|
6
|
+
results: UgcProcessingResult[];
|
|
7
|
+
};
|
|
8
|
+
export declare function runWorkerUgcTask(input: {
|
|
9
|
+
client: ApiClient;
|
|
10
|
+
assignment: WorkerUgcTaskAssignmentV5;
|
|
11
|
+
workerKey: string;
|
|
12
|
+
leaseToken: string;
|
|
13
|
+
}): Promise<void>;
|