pixelkiln 0.66.0 → 0.67.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/dist/cli.js +730 -475
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +659 -441
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +671 -269
- package/dist/index.d.ts +671 -269
- package/dist/index.js +659 -441
- package/dist/index.js.map +1 -1
- package/docs/CLI.md +17 -0
- package/docs/MANIFEST.md +6 -3
- package/docs/PIXELLAB.md +15 -14
- package/docs/REVISIONS.md +98 -10
- package/package.json +1 -1
- package/schema/manifest.schema.json +13 -0
- package/skills/pixelkiln/references/pixellab-roadmap.md +38 -15
- package/skills/pixelkiln/references/pixellab.md +35 -20
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ var RevisionModeSchema = z.enum([
|
|
|
11
11
|
"correct-pixelart",
|
|
12
12
|
"animate",
|
|
13
13
|
"animate-pixminimax",
|
|
14
|
+
"animate-skeleton",
|
|
14
15
|
"interpolate",
|
|
15
16
|
"edit-animation"
|
|
16
17
|
]);
|
|
@@ -329,6 +330,30 @@ var RevisionSchema = z.object({
|
|
|
329
330
|
direction: CharacterDirectionSchema.optional(),
|
|
330
331
|
/** `animate`/`animate-pixminimax` only: let PixelLab expand the action into a fuller motion description first. */
|
|
331
332
|
enhancePrompt: z.boolean().optional(),
|
|
333
|
+
/**
|
|
334
|
+
* `animate-skeleton` only: manifest-relative path to a committed
|
|
335
|
+
* `SkeletonSet` JSON file (see `src/skeleton.ts`) — the pose the parent
|
|
336
|
+
* image is already in, plus 3-15 per-frame poses for the motion.
|
|
337
|
+
* Authored via `pixelkiln estimate-skeleton`, then hand-tweaked; never
|
|
338
|
+
* inline in the manifest, the same reasoning `mask`/`lastFrame` are
|
|
339
|
+
* committed files rather than inline pixel data.
|
|
340
|
+
*/
|
|
341
|
+
keypointsFile: z.string().min(1).optional(),
|
|
342
|
+
/**
|
|
343
|
+
* `animate-skeleton` only: the body a joint's missing `depth` is taken
|
|
344
|
+
* from. PixelLab's default is `mannequin`; free string like `character`'s
|
|
345
|
+
* own `template` field, validated at the provider layer against the
|
|
346
|
+
* same `mannequin`/`bear`/`cat`/`dog`/`horse`/`lion` vocabulary.
|
|
347
|
+
*/
|
|
348
|
+
skeletonTemplate: z.string().min(1).optional(),
|
|
349
|
+
/**
|
|
350
|
+
* `animate-skeleton` only: what the character *looks like*, a noun
|
|
351
|
+
* phrase (colours, clothing, held items) — distinct from the asset's
|
|
352
|
+
* own `prompt`, which this mode sends as the motion's short label
|
|
353
|
+
* (PixelLab's `action`), the same `prompt`-as-motion convention
|
|
354
|
+
* `animate`/`animate-pixminimax` already use.
|
|
355
|
+
*/
|
|
356
|
+
description: z.string().min(1).optional(),
|
|
332
357
|
/**
|
|
333
358
|
* `image-to-image`/`inpaint` only: which provider engine draws the
|
|
334
359
|
* edit. `pro-flash` selects PixelLab's Pro Flash edit and inpaint tier
|
|
@@ -419,18 +444,41 @@ var RevisionSchema = z.object({
|
|
|
419
444
|
path: ["fps"]
|
|
420
445
|
});
|
|
421
446
|
}
|
|
422
|
-
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax") {
|
|
447
|
+
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax" && revision.mode !== "animate-skeleton") {
|
|
423
448
|
context.addIssue({
|
|
424
449
|
code: z.ZodIssueCode.custom,
|
|
425
|
-
message: "direction applies to animate-pixminimax revisions only",
|
|
450
|
+
message: "direction applies to animate-pixminimax/animate-skeleton revisions only",
|
|
451
|
+
path: ["direction"]
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
if (revision.mode === "animate-skeleton" && revision.direction === void 0) {
|
|
455
|
+
context.addIssue({
|
|
456
|
+
code: z.ZodIssueCode.custom,
|
|
457
|
+
message: "animate-skeleton revisions require a direction",
|
|
426
458
|
path: ["direction"]
|
|
427
459
|
});
|
|
428
460
|
}
|
|
429
461
|
if (revision.frames !== void 0 && revision.frames % 2 !== 0) {
|
|
430
462
|
context.addIssue({ code: z.ZodIssueCode.custom, message: "frames must be even", path: ["frames"] });
|
|
431
463
|
}
|
|
464
|
+
if (revision.mode === "animate-skeleton" && !revision.keypointsFile) {
|
|
465
|
+
context.addIssue({
|
|
466
|
+
code: z.ZodIssueCode.custom,
|
|
467
|
+
message: "animate-skeleton revisions require keypointsFile",
|
|
468
|
+
path: ["keypointsFile"]
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
for (const field of ["keypointsFile", "skeletonTemplate", "description"]) {
|
|
472
|
+
if (revision[field] !== void 0 && revision.mode !== "animate-skeleton") {
|
|
473
|
+
context.addIssue({
|
|
474
|
+
code: z.ZodIssueCode.custom,
|
|
475
|
+
message: `${field} applies to animate-skeleton revisions only`,
|
|
476
|
+
path: [field]
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}
|
|
432
480
|
});
|
|
433
|
-
var FRAME_SET_REVISION_MODES = ["animate", "animate-pixminimax", "interpolate", "edit-animation"];
|
|
481
|
+
var FRAME_SET_REVISION_MODES = ["animate", "animate-pixminimax", "animate-skeleton", "interpolate", "edit-animation"];
|
|
434
482
|
var MEMBER_SET_REVISION_MODES = ["reduce-colors", "correct-pixelart", "edit-animation"];
|
|
435
483
|
var StyleObjectSchema = z.object({
|
|
436
484
|
/** Generation backend for this style. Omit to inherit the manifest default. */
|
|
@@ -1062,11 +1110,16 @@ var LockEntrySchema = z.object({
|
|
|
1062
1110
|
paletteImageSha256: z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1063
1111
|
dithering: RevisionDitheringSchema.optional(),
|
|
1064
1112
|
ditheringStrength: z.number().min(0).max(10).optional(),
|
|
1065
|
-
|
|
1113
|
+
// 4-40 for animate/animate-pixminimax; animate-skeleton's own 3-15
|
|
1114
|
+
// range extends the floor down to 3, hence min(3) here rather than 4.
|
|
1115
|
+
frames: z.number().int().min(3).max(40).optional(),
|
|
1066
1116
|
fps: z.number().int().min(1).max(60).optional(),
|
|
1067
1117
|
lastFrameSha256: z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1068
1118
|
direction: CharacterDirectionSchema.optional(),
|
|
1069
1119
|
enhancePrompt: z.boolean().optional(),
|
|
1120
|
+
keypointsSha256: z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1121
|
+
skeletonTemplate: z.string().min(1).optional(),
|
|
1122
|
+
description: z.string().min(1).optional(),
|
|
1070
1123
|
engine: z.enum(["pro-flash"]).optional()
|
|
1071
1124
|
}).strict().nullable().default(null),
|
|
1072
1125
|
/** For a mirror: the asset it flips and a hash over that asset's output hashes when this was made. */
|
|
@@ -1253,7 +1306,7 @@ function exitCodeFor(err) {
|
|
|
1253
1306
|
}
|
|
1254
1307
|
|
|
1255
1308
|
// src/client.ts
|
|
1256
|
-
import { z as
|
|
1309
|
+
import { z as z3 } from "zod";
|
|
1257
1310
|
|
|
1258
1311
|
// src/http.ts
|
|
1259
1312
|
var MAX_RETRIES = 4;
|
|
@@ -1303,262 +1356,289 @@ function fetchWithRetry(request, opts = {}) {
|
|
|
1303
1356
|
};
|
|
1304
1357
|
}
|
|
1305
1358
|
|
|
1359
|
+
// src/skeleton.ts
|
|
1360
|
+
import { z as z2 } from "zod";
|
|
1361
|
+
var SkeletonKeypointSchema = z2.object({
|
|
1362
|
+
label: z2.string().min(1),
|
|
1363
|
+
x: z2.number().min(0).max(1),
|
|
1364
|
+
y: z2.number().min(0).max(1),
|
|
1365
|
+
z_index: z2.number(),
|
|
1366
|
+
depth: z2.number().optional()
|
|
1367
|
+
}).strict();
|
|
1368
|
+
var SkeletonFrameSchema = z2.array(SkeletonKeypointSchema).length(18);
|
|
1369
|
+
var SkeletonSetSchema = z2.object({
|
|
1370
|
+
firstFrameKeypoints: SkeletonFrameSchema,
|
|
1371
|
+
frames: z2.array(SkeletonFrameSchema).min(3).max(15)
|
|
1372
|
+
}).strict();
|
|
1373
|
+
function parseSkeletonSet(json, file) {
|
|
1374
|
+
const result = SkeletonSetSchema.safeParse(json);
|
|
1375
|
+
if (!result.success) {
|
|
1376
|
+
const issues = result.error.issues.slice(0, 4).map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join("; ");
|
|
1377
|
+
throw new Error(`revision keypoints file ${file} does not match the expected shape: ${issues}`);
|
|
1378
|
+
}
|
|
1379
|
+
return result.data;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1306
1382
|
// src/client.ts
|
|
1307
1383
|
var BASE = process.env.PIXELLAB_API_BASE ?? "https://api.pixellab.ai/v2";
|
|
1308
1384
|
var MAX_DOWNLOAD_BYTES = 64 * 1024 * 1024;
|
|
1309
|
-
var BalanceResponseSchema =
|
|
1310
|
-
credits:
|
|
1311
|
-
subscription:
|
|
1312
|
-
generations:
|
|
1313
|
-
total:
|
|
1314
|
-
plan:
|
|
1385
|
+
var BalanceResponseSchema = z3.object({
|
|
1386
|
+
credits: z3.object({ usd: z3.number() }).passthrough(),
|
|
1387
|
+
subscription: z3.object({
|
|
1388
|
+
generations: z3.number(),
|
|
1389
|
+
total: z3.number(),
|
|
1390
|
+
plan: z3.string().nullable().optional()
|
|
1315
1391
|
}).passthrough()
|
|
1316
1392
|
}).passthrough();
|
|
1317
|
-
var ObjectSubmitSchema =
|
|
1318
|
-
background_job_id:
|
|
1319
|
-
object_id:
|
|
1320
|
-
status:
|
|
1321
|
-
n_frames:
|
|
1393
|
+
var ObjectSubmitSchema = z3.object({
|
|
1394
|
+
background_job_id: z3.string().min(1),
|
|
1395
|
+
object_id: z3.string().min(1),
|
|
1396
|
+
status: z3.string().default("queued"),
|
|
1397
|
+
n_frames: z3.number().int().min(0)
|
|
1322
1398
|
}).passthrough();
|
|
1323
|
-
var MapSubmitSchema =
|
|
1324
|
-
background_job_id:
|
|
1325
|
-
object_id:
|
|
1326
|
-
status:
|
|
1399
|
+
var MapSubmitSchema = z3.object({
|
|
1400
|
+
background_job_id: z3.string().min(1),
|
|
1401
|
+
object_id: z3.string().min(1),
|
|
1402
|
+
status: z3.string().default("processing")
|
|
1327
1403
|
}).passthrough();
|
|
1328
|
-
var UsageSchema =
|
|
1329
|
-
type:
|
|
1330
|
-
usd:
|
|
1331
|
-
generations:
|
|
1404
|
+
var UsageSchema = z3.object({
|
|
1405
|
+
type: z3.string().optional(),
|
|
1406
|
+
usd: z3.number().nullable().optional(),
|
|
1407
|
+
generations: z3.number().nullable().optional()
|
|
1332
1408
|
}).passthrough().nullable().optional();
|
|
1333
|
-
var TilesSubmitSchema =
|
|
1334
|
-
tile_id:
|
|
1335
|
-
background_job_id:
|
|
1336
|
-
status:
|
|
1409
|
+
var TilesSubmitSchema = z3.object({
|
|
1410
|
+
tile_id: z3.string().min(1),
|
|
1411
|
+
background_job_id: z3.string().min(1),
|
|
1412
|
+
status: z3.literal("processing").default("processing")
|
|
1337
1413
|
}).passthrough();
|
|
1338
|
-
var TilesProSchema =
|
|
1339
|
-
storage_urls:
|
|
1340
|
-
kind:
|
|
1341
|
-
tile_rules:
|
|
1414
|
+
var TilesProSchema = z3.object({
|
|
1415
|
+
storage_urls: z3.record(z3.string()),
|
|
1416
|
+
kind: z3.string().nullable().default(null),
|
|
1417
|
+
tile_rules: z3.record(z3.unknown()).nullable().optional()
|
|
1342
1418
|
}).passthrough();
|
|
1343
|
-
var TilesetSubmitSchema =
|
|
1344
|
-
tileset_id:
|
|
1345
|
-
background_job_id:
|
|
1346
|
-
status:
|
|
1419
|
+
var TilesetSubmitSchema = z3.object({
|
|
1420
|
+
tileset_id: z3.string().min(1),
|
|
1421
|
+
background_job_id: z3.string().min(1),
|
|
1422
|
+
status: z3.literal("processing").default("processing")
|
|
1347
1423
|
}).passthrough();
|
|
1348
|
-
var TilesetTileSchema =
|
|
1349
|
-
id:
|
|
1350
|
-
name:
|
|
1351
|
-
image:
|
|
1352
|
-
corners:
|
|
1353
|
-
pattern_4x4:
|
|
1354
|
-
row_0:
|
|
1355
|
-
row_1:
|
|
1356
|
-
row_2:
|
|
1357
|
-
row_3:
|
|
1424
|
+
var TilesetTileSchema = z3.object({
|
|
1425
|
+
id: z3.string().min(1),
|
|
1426
|
+
name: z3.string(),
|
|
1427
|
+
image: z3.object({ base64: z3.string().min(1), format: z3.string().default("png") }).passthrough(),
|
|
1428
|
+
corners: z3.object({ NW: z3.string(), NE: z3.string(), SW: z3.string(), SE: z3.string() }).passthrough(),
|
|
1429
|
+
pattern_4x4: z3.object({
|
|
1430
|
+
row_0: z3.array(z3.number()),
|
|
1431
|
+
row_1: z3.array(z3.number()),
|
|
1432
|
+
row_2: z3.array(z3.number()),
|
|
1433
|
+
row_3: z3.array(z3.number())
|
|
1358
1434
|
}).passthrough()
|
|
1359
1435
|
}).passthrough();
|
|
1360
|
-
var TilesetGetSchema =
|
|
1361
|
-
tileset:
|
|
1362
|
-
total_tiles:
|
|
1363
|
-
tile_size:
|
|
1364
|
-
terrain_types:
|
|
1365
|
-
tiles:
|
|
1436
|
+
var TilesetGetSchema = z3.object({
|
|
1437
|
+
tileset: z3.object({
|
|
1438
|
+
total_tiles: z3.number().int().min(1),
|
|
1439
|
+
tile_size: z3.object({ width: z3.number().int().positive(), height: z3.number().int().positive() }).passthrough(),
|
|
1440
|
+
terrain_types: z3.array(z3.string()),
|
|
1441
|
+
tiles: z3.array(TilesetTileSchema).min(1)
|
|
1366
1442
|
}).passthrough(),
|
|
1367
1443
|
usage: UsageSchema
|
|
1368
1444
|
}).passthrough();
|
|
1369
|
-
var IsometricTileSubmitSchema =
|
|
1370
|
-
tile_id:
|
|
1371
|
-
background_job_id:
|
|
1372
|
-
status:
|
|
1445
|
+
var IsometricTileSubmitSchema = z3.object({
|
|
1446
|
+
tile_id: z3.string().min(1),
|
|
1447
|
+
background_job_id: z3.string().min(1),
|
|
1448
|
+
status: z3.literal("processing").default("processing")
|
|
1373
1449
|
}).passthrough();
|
|
1374
|
-
var IsometricTileGetSchema =
|
|
1375
|
-
image:
|
|
1450
|
+
var IsometricTileGetSchema = z3.object({
|
|
1451
|
+
image: z3.object({ base64: z3.string().min(1), format: z3.string().default("png") }).passthrough(),
|
|
1376
1452
|
usage: UsageSchema
|
|
1377
1453
|
}).passthrough();
|
|
1378
|
-
var UiAssetSubmitSchema =
|
|
1379
|
-
ui_asset_id:
|
|
1380
|
-
background_job_id:
|
|
1381
|
-
status:
|
|
1454
|
+
var UiAssetSubmitSchema = z3.object({
|
|
1455
|
+
ui_asset_id: z3.string().min(1),
|
|
1456
|
+
background_job_id: z3.string().min(1),
|
|
1457
|
+
status: z3.string().default("processing"),
|
|
1382
1458
|
usage: UsageSchema
|
|
1383
1459
|
}).passthrough();
|
|
1384
|
-
var UiAssetGetSchema =
|
|
1385
|
-
id:
|
|
1386
|
-
status:
|
|
1387
|
-
image_url:
|
|
1388
|
-
progress_percent:
|
|
1389
|
-
eta_seconds:
|
|
1460
|
+
var UiAssetGetSchema = z3.object({
|
|
1461
|
+
id: z3.string().min(1),
|
|
1462
|
+
status: z3.string().nullable().default(null),
|
|
1463
|
+
image_url: z3.string().nullable().optional(),
|
|
1464
|
+
progress_percent: z3.number().nullable().optional(),
|
|
1465
|
+
eta_seconds: z3.number().nullable().optional()
|
|
1390
1466
|
}).passthrough();
|
|
1391
|
-
var RevisionJobSubmitSchema =
|
|
1392
|
-
background_job_id:
|
|
1393
|
-
status:
|
|
1467
|
+
var RevisionJobSubmitSchema = z3.object({
|
|
1468
|
+
background_job_id: z3.string().min(1),
|
|
1469
|
+
status: z3.string().default("processing")
|
|
1394
1470
|
}).passthrough();
|
|
1395
|
-
var ObjectAnimationGroupSchema =
|
|
1396
|
-
animation_group_id:
|
|
1397
|
-
display_name:
|
|
1398
|
-
description:
|
|
1399
|
-
frame_count:
|
|
1400
|
-
directions:
|
|
1401
|
-
|
|
1402
|
-
direction:
|
|
1403
|
-
storage_urls:
|
|
1404
|
-
created_at:
|
|
1471
|
+
var ObjectAnimationGroupSchema = z3.object({
|
|
1472
|
+
animation_group_id: z3.string().min(1),
|
|
1473
|
+
display_name: z3.string().nullable().default(null),
|
|
1474
|
+
description: z3.string().default(""),
|
|
1475
|
+
frame_count: z3.number().int().default(0),
|
|
1476
|
+
directions: z3.array(
|
|
1477
|
+
z3.object({
|
|
1478
|
+
direction: z3.string(),
|
|
1479
|
+
storage_urls: z3.record(z3.unknown()).default({}),
|
|
1480
|
+
created_at: z3.string()
|
|
1405
1481
|
}).passthrough()
|
|
1406
1482
|
).default([])
|
|
1407
1483
|
}).passthrough();
|
|
1408
|
-
var PixelLabObjectSchema =
|
|
1409
|
-
id:
|
|
1410
|
-
name:
|
|
1411
|
-
state_name:
|
|
1412
|
-
prompt:
|
|
1413
|
-
size:
|
|
1414
|
-
directions:
|
|
1415
|
-
created_at:
|
|
1416
|
-
view:
|
|
1417
|
-
preview_url:
|
|
1418
|
-
rotation_urls:
|
|
1419
|
-
frame_urls:
|
|
1420
|
-
tags:
|
|
1421
|
-
status:
|
|
1422
|
-
progress_percent:
|
|
1423
|
-
eta_seconds:
|
|
1424
|
-
group_id:
|
|
1425
|
-
animations:
|
|
1484
|
+
var PixelLabObjectSchema = z3.object({
|
|
1485
|
+
id: z3.string().min(1),
|
|
1486
|
+
name: z3.string().nullable().default(null),
|
|
1487
|
+
state_name: z3.string().nullable().optional(),
|
|
1488
|
+
prompt: z3.string().default(""),
|
|
1489
|
+
size: z3.object({ width: z3.number().int().positive(), height: z3.number().int().positive() }),
|
|
1490
|
+
directions: z3.number().default(0),
|
|
1491
|
+
created_at: z3.string(),
|
|
1492
|
+
view: z3.string().nullable().default(null),
|
|
1493
|
+
preview_url: z3.string().nullable().optional(),
|
|
1494
|
+
rotation_urls: z3.record(z3.string().nullable()).nullable().optional(),
|
|
1495
|
+
frame_urls: z3.array(z3.string()).nullable().optional(),
|
|
1496
|
+
tags: z3.array(z3.string()).default([]),
|
|
1497
|
+
status: z3.string().nullable().default(null),
|
|
1498
|
+
progress_percent: z3.number().nullable().optional(),
|
|
1499
|
+
eta_seconds: z3.number().nullable().optional(),
|
|
1500
|
+
group_id: z3.string().nullable().optional(),
|
|
1501
|
+
animations: z3.array(ObjectAnimationGroupSchema).default([])
|
|
1502
|
+
}).passthrough();
|
|
1503
|
+
var MapObjectSchema = z3.object({
|
|
1504
|
+
object_id: z3.string().min(1),
|
|
1505
|
+
status: z3.string(),
|
|
1506
|
+
description: z3.string().nullable().default(null),
|
|
1507
|
+
width: z3.number().nullable().default(null),
|
|
1508
|
+
height: z3.number().nullable().default(null),
|
|
1509
|
+
download_url: z3.string().nullable().default(null)
|
|
1426
1510
|
}).passthrough();
|
|
1427
|
-
var
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1511
|
+
var ObjectListSchema = z3.object({ objects: z3.array(PixelLabObjectSchema), total: z3.number().int().min(0) }).passthrough();
|
|
1512
|
+
var PixfluxResponseSchema = z3.object({ image: z3.object({ base64: z3.string().min(1) }).passthrough(), usage: z3.unknown().optional() }).passthrough();
|
|
1513
|
+
var ReduceColorsResponseSchema = z3.object({
|
|
1514
|
+
images: z3.array(z3.object({ base64: z3.string().min(1) }).passthrough()).min(1),
|
|
1515
|
+
palette: z3.object({ base64: z3.string().min(1) }).passthrough(),
|
|
1516
|
+
n_colors: z3.number().int(),
|
|
1517
|
+
usage: z3.unknown().optional()
|
|
1434
1518
|
}).passthrough();
|
|
1435
|
-
var
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
images: z2.array(z2.object({ base64: z2.string().min(1) }).passthrough()).min(1),
|
|
1439
|
-
palette: z2.object({ base64: z2.string().min(1) }).passthrough(),
|
|
1440
|
-
n_colors: z2.number().int(),
|
|
1441
|
-
usage: z2.unknown().optional()
|
|
1519
|
+
var CorrectPixelartResponseSchema = z3.object({
|
|
1520
|
+
images: z3.array(z3.object({ base64: z3.string().min(1) }).passthrough()).min(1),
|
|
1521
|
+
usage: z3.unknown().optional()
|
|
1442
1522
|
}).passthrough();
|
|
1443
|
-
var
|
|
1444
|
-
|
|
1445
|
-
|
|
1523
|
+
var ProFlashImageSubmitSchema = z3.object({
|
|
1524
|
+
background_job_id: z3.string().min(1),
|
|
1525
|
+
image_id: z3.string().min(1),
|
|
1526
|
+
source_image_id: z3.string().min(1),
|
|
1527
|
+
status: z3.string().default("processing"),
|
|
1528
|
+
estimated_generations: z3.number().nullable().optional(),
|
|
1529
|
+
usage: z3.unknown().optional()
|
|
1446
1530
|
}).passthrough();
|
|
1447
|
-
var
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
usage: z2.unknown().optional()
|
|
1531
|
+
var UnzoomResponseSchema = z3.object({
|
|
1532
|
+
image: z3.object({ base64: z3.string().min(1) }).passthrough(),
|
|
1533
|
+
original_size: z3.object({ width: z3.number().int(), height: z3.number().int() }).passthrough(),
|
|
1534
|
+
unzoomed_size: z3.object({ width: z3.number().int(), height: z3.number().int() }).passthrough(),
|
|
1535
|
+
zoom_factor_detected: z3.number(),
|
|
1536
|
+
usage: z3.unknown().optional()
|
|
1454
1537
|
}).passthrough();
|
|
1455
|
-
var
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1538
|
+
var FontJobSchema = z3.object({
|
|
1539
|
+
job_id: z3.string().min(1),
|
|
1540
|
+
status: z3.string(),
|
|
1541
|
+
glyph_px: z3.number().int().nullable().optional(),
|
|
1542
|
+
download_atlas_url: z3.string().nullable().optional(),
|
|
1543
|
+
download_ttf_url: z3.string().nullable().optional(),
|
|
1544
|
+
usage: z3.unknown().optional()
|
|
1461
1545
|
}).passthrough();
|
|
1462
|
-
var
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
download_atlas_url: z2.string().nullable().optional(),
|
|
1467
|
-
download_ttf_url: z2.string().nullable().optional(),
|
|
1468
|
-
usage: z2.unknown().optional()
|
|
1546
|
+
var SelectFramesSchema = z3.object({ created_object_ids: z3.array(z3.string()) }).passthrough();
|
|
1547
|
+
var EstimateSkeletonResponseSchema = z3.object({
|
|
1548
|
+
keypoints: z3.array(SkeletonKeypointSchema).length(18),
|
|
1549
|
+
usage: z3.unknown().optional()
|
|
1469
1550
|
}).passthrough();
|
|
1470
|
-
var
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
status: z2.string().default("processing"),
|
|
1551
|
+
var CharacterSubmitSchema = z3.object({
|
|
1552
|
+
background_job_id: z3.string().min(1),
|
|
1553
|
+
character_id: z3.string().min(1),
|
|
1554
|
+
status: z3.string().default("processing"),
|
|
1475
1555
|
usage: UsageSchema
|
|
1476
1556
|
}).passthrough();
|
|
1477
|
-
var AnimateSubmitSchema =
|
|
1478
|
-
background_job_ids:
|
|
1479
|
-
directions:
|
|
1480
|
-
status:
|
|
1557
|
+
var AnimateSubmitSchema = z3.object({
|
|
1558
|
+
background_job_ids: z3.array(z3.string()),
|
|
1559
|
+
directions: z3.array(z3.string()),
|
|
1560
|
+
status: z3.string().default("processing"),
|
|
1481
1561
|
usage: UsageSchema
|
|
1482
1562
|
}).passthrough();
|
|
1483
|
-
var ObjectProSubmitSchema =
|
|
1484
|
-
object_id:
|
|
1485
|
-
background_job_id:
|
|
1486
|
-
status:
|
|
1563
|
+
var ObjectProSubmitSchema = z3.object({
|
|
1564
|
+
object_id: z3.string().min(1),
|
|
1565
|
+
background_job_id: z3.string().min(1),
|
|
1566
|
+
status: z3.string().default("processing"),
|
|
1487
1567
|
usage: UsageSchema
|
|
1488
1568
|
}).passthrough();
|
|
1489
|
-
var DirectionSubmissionSchema =
|
|
1490
|
-
direction:
|
|
1491
|
-
status:
|
|
1492
|
-
background_job_id:
|
|
1493
|
-
animation_id:
|
|
1569
|
+
var DirectionSubmissionSchema = z3.object({
|
|
1570
|
+
direction: z3.string(),
|
|
1571
|
+
status: z3.string(),
|
|
1572
|
+
background_job_id: z3.string().nullable().default(null),
|
|
1573
|
+
animation_id: z3.string().nullable().default(null)
|
|
1494
1574
|
}).passthrough();
|
|
1495
|
-
var AnimateObjectSubmitSchema =
|
|
1496
|
-
animation_group_id:
|
|
1497
|
-
object_id:
|
|
1498
|
-
mode:
|
|
1499
|
-
frame_count:
|
|
1500
|
-
display_name:
|
|
1501
|
-
description:
|
|
1502
|
-
submissions:
|
|
1575
|
+
var AnimateObjectSubmitSchema = z3.object({
|
|
1576
|
+
animation_group_id: z3.string().min(1),
|
|
1577
|
+
object_id: z3.string().min(1),
|
|
1578
|
+
mode: z3.string(),
|
|
1579
|
+
frame_count: z3.number().int(),
|
|
1580
|
+
display_name: z3.string().nullable().default(null),
|
|
1581
|
+
description: z3.string().default(""),
|
|
1582
|
+
submissions: z3.array(DirectionSubmissionSchema),
|
|
1503
1583
|
usage: UsageSchema
|
|
1504
1584
|
}).passthrough();
|
|
1505
|
-
var PortraitSubmitSchema =
|
|
1506
|
-
background_job_id:
|
|
1507
|
-
status:
|
|
1585
|
+
var PortraitSubmitSchema = z3.object({
|
|
1586
|
+
background_job_id: z3.string().min(1),
|
|
1587
|
+
status: z3.string().default("processing"),
|
|
1508
1588
|
usage: UsageSchema
|
|
1509
1589
|
}).passthrough();
|
|
1510
|
-
var PortraitJobSchema =
|
|
1511
|
-
status:
|
|
1512
|
-
download_url:
|
|
1513
|
-
width:
|
|
1514
|
-
height:
|
|
1590
|
+
var PortraitJobSchema = z3.object({
|
|
1591
|
+
status: z3.string(),
|
|
1592
|
+
download_url: z3.string().nullable().optional(),
|
|
1593
|
+
width: z3.number().int().nullable().optional(),
|
|
1594
|
+
height: z3.number().int().nullable().optional()
|
|
1515
1595
|
}).passthrough();
|
|
1516
|
-
var SetPortraitSchema =
|
|
1517
|
-
character_id:
|
|
1518
|
-
size:
|
|
1519
|
-
url:
|
|
1596
|
+
var SetPortraitSchema = z3.object({
|
|
1597
|
+
character_id: z3.string().min(1),
|
|
1598
|
+
size: z3.number().int().positive(),
|
|
1599
|
+
url: z3.string().min(1),
|
|
1520
1600
|
usage: UsageSchema
|
|
1521
1601
|
}).passthrough();
|
|
1522
|
-
var TransferOutfitSubmitSchema =
|
|
1523
|
-
background_job_id:
|
|
1524
|
-
status:
|
|
1602
|
+
var TransferOutfitSubmitSchema = z3.object({
|
|
1603
|
+
background_job_id: z3.string().min(1),
|
|
1604
|
+
status: z3.string().default("processing"),
|
|
1525
1605
|
usage: UsageSchema
|
|
1526
1606
|
}).passthrough();
|
|
1527
|
-
var CharacterAnimationDirectionSchema =
|
|
1528
|
-
direction:
|
|
1529
|
-
frame_count:
|
|
1530
|
-
frames:
|
|
1607
|
+
var CharacterAnimationDirectionSchema = z3.object({
|
|
1608
|
+
direction: z3.string(),
|
|
1609
|
+
frame_count: z3.number().int().min(0),
|
|
1610
|
+
frames: z3.array(z3.string())
|
|
1531
1611
|
}).passthrough();
|
|
1532
|
-
var CharacterAnimationSchema2 =
|
|
1533
|
-
animation_type:
|
|
1534
|
-
display_name:
|
|
1535
|
-
animation_group_id:
|
|
1536
|
-
directions:
|
|
1612
|
+
var CharacterAnimationSchema2 = z3.object({
|
|
1613
|
+
animation_type: z3.string(),
|
|
1614
|
+
display_name: z3.string().nullable().optional(),
|
|
1615
|
+
animation_group_id: z3.string().nullable().optional(),
|
|
1616
|
+
directions: z3.array(CharacterAnimationDirectionSchema)
|
|
1537
1617
|
}).passthrough();
|
|
1538
|
-
var CharacterSchema =
|
|
1539
|
-
id:
|
|
1540
|
-
name:
|
|
1541
|
-
state_name:
|
|
1542
|
-
prompt:
|
|
1543
|
-
size:
|
|
1544
|
-
directions:
|
|
1545
|
-
created_at:
|
|
1546
|
-
updated_at:
|
|
1547
|
-
animation_count:
|
|
1548
|
-
template_id:
|
|
1549
|
-
view:
|
|
1550
|
-
status:
|
|
1551
|
-
rotation_urls:
|
|
1552
|
-
tags:
|
|
1553
|
-
group_id:
|
|
1554
|
-
animations:
|
|
1555
|
-
preview_url:
|
|
1618
|
+
var CharacterSchema = z3.object({
|
|
1619
|
+
id: z3.string().min(1),
|
|
1620
|
+
name: z3.string().default(""),
|
|
1621
|
+
state_name: z3.string().nullable().optional(),
|
|
1622
|
+
prompt: z3.string().default(""),
|
|
1623
|
+
size: z3.object({ width: z3.number().int().positive(), height: z3.number().int().positive() }),
|
|
1624
|
+
directions: z3.number().int(),
|
|
1625
|
+
created_at: z3.string(),
|
|
1626
|
+
updated_at: z3.string().nullable().optional(),
|
|
1627
|
+
animation_count: z3.number().int().default(0),
|
|
1628
|
+
template_id: z3.string().default("mannequin"),
|
|
1629
|
+
view: z3.string().nullable().optional(),
|
|
1630
|
+
status: z3.string().default("completed"),
|
|
1631
|
+
rotation_urls: z3.record(z3.string().nullable()).nullable().optional(),
|
|
1632
|
+
tags: z3.array(z3.string()).default([]),
|
|
1633
|
+
group_id: z3.string().nullable().optional(),
|
|
1634
|
+
animations: z3.array(CharacterAnimationSchema2).default([]),
|
|
1635
|
+
preview_url: z3.string().nullable().optional()
|
|
1556
1636
|
}).passthrough();
|
|
1557
|
-
var CharacterListSchema =
|
|
1558
|
-
var BackgroundJobSchema =
|
|
1559
|
-
id:
|
|
1560
|
-
status:
|
|
1561
|
-
last_response:
|
|
1637
|
+
var CharacterListSchema = z3.object({ characters: z3.array(CharacterSchema), total: z3.number().int().min(0) }).passthrough();
|
|
1638
|
+
var BackgroundJobSchema = z3.object({
|
|
1639
|
+
id: z3.string(),
|
|
1640
|
+
status: z3.string(),
|
|
1641
|
+
last_response: z3.record(z3.unknown()).nullable().optional(),
|
|
1562
1642
|
/**
|
|
1563
1643
|
* The billed amount, confirmed live for a `map` object and a standard
|
|
1564
1644
|
* character base (docs/ENDPOINTS.md, "Limits and billing"); duplicated at
|
|
@@ -1566,7 +1646,7 @@ var BackgroundJobSchema = z2.object({
|
|
|
1566
1646
|
*/
|
|
1567
1647
|
usage: UsageSchema
|
|
1568
1648
|
}).passthrough();
|
|
1569
|
-
var DeleteAnimationsSchema =
|
|
1649
|
+
var DeleteAnimationsSchema = z3.object({ success: z3.boolean(), deleted_count: z3.number().int().default(0), error: z3.string().nullable().optional() }).passthrough();
|
|
1570
1650
|
function validateResponse(schema, raw, operation) {
|
|
1571
1651
|
const parsed = schema.safeParse(raw);
|
|
1572
1652
|
if (parsed.success) return parsed.data;
|
|
@@ -2597,6 +2677,61 @@ var PixelLabClient = class {
|
|
|
2597
2677
|
"animate-pixminimax"
|
|
2598
2678
|
);
|
|
2599
2679
|
}
|
|
2680
|
+
/**
|
|
2681
|
+
* `/animate-with-skeleton-v3`, beta (tier 1 subscription or higher): poses
|
|
2682
|
+
* one reference image frame-by-frame from a supplied skeleton per frame,
|
|
2683
|
+
* rather than a text motion description. Confirmed against the live
|
|
2684
|
+
* `animate_with_skeleton_v3` MCP tool schema (the same authoritative
|
|
2685
|
+
* source this codebase already treats as ground truth for the
|
|
2686
|
+
* character/object family) — `action`/`description` are both real,
|
|
2687
|
+
* optional wire fields, contrary to an initial guess that this endpoint
|
|
2688
|
+
* took no text input at all; `direction`/`keypoints`/`firstFrameKeypoints`
|
|
2689
|
+
* are required. The example keypoint from that same tool schema,
|
|
2690
|
+
* `{"label": "RIGHT KNEE", "x": 0.52, "y": 0.71, "z_index": 9}`, is what
|
|
2691
|
+
* `SkeletonKeypointSchema` (`src/skeleton.ts`) models. Same
|
|
2692
|
+
* unverified-completed-shape caveat as `animateWithTextV3`/
|
|
2693
|
+
* `animatePixminimax` above — this endpoint has never been called against
|
|
2694
|
+
* a live account by this codebase.
|
|
2695
|
+
*/
|
|
2696
|
+
async animateWithSkeletonV3(args) {
|
|
2697
|
+
const body = {
|
|
2698
|
+
first_frame: args.firstFrame,
|
|
2699
|
+
first_frame_keypoints: args.firstFrameKeypoints,
|
|
2700
|
+
keypoints: args.keypoints,
|
|
2701
|
+
direction: args.direction
|
|
2702
|
+
};
|
|
2703
|
+
if (args.templateId) body.template_id = args.templateId;
|
|
2704
|
+
if (args.action) body.action = args.action;
|
|
2705
|
+
if (args.description) body.description = args.description;
|
|
2706
|
+
if (args.seed != null) body.seed = args.seed;
|
|
2707
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
2708
|
+
return validateResponse(
|
|
2709
|
+
RevisionJobSubmitSchema,
|
|
2710
|
+
await this.request("/animate-with-skeleton-v3", { method: "POST", body: JSON.stringify(body) }),
|
|
2711
|
+
"animate-with-skeleton-v3"
|
|
2712
|
+
);
|
|
2713
|
+
}
|
|
2714
|
+
/**
|
|
2715
|
+
* `/estimate-skeleton`: auto-derives a reference image's own 18-joint
|
|
2716
|
+
* keypoints, directly usable as `animateWithSkeletonV3`'s
|
|
2717
|
+
* `firstFrameKeypoints` (or, run against a candidate pose image, as one
|
|
2718
|
+
* entry of its `keypoints` sequence). Not called anywhere in this
|
|
2719
|
+
* codebase's own submit/poll pipeline — deliberately kept outside it (see
|
|
2720
|
+
* `runEstimateSkeleton` in `src/cli/commands`) so the only PixelLab
|
|
2721
|
+
* endpoint composed into `animate-with-skeleton-v3`'s submission is that
|
|
2722
|
+
* one endpoint itself, not two unverified calls chained together.
|
|
2723
|
+
* Synchronous per this endpoint's own framing; unverified against a live
|
|
2724
|
+
* account (see `EstimateSkeletonResponseSchema`'s own caveat).
|
|
2725
|
+
*/
|
|
2726
|
+
async estimateSkeleton(args) {
|
|
2727
|
+
const body = { image: args.image };
|
|
2728
|
+
const res = validateResponse(
|
|
2729
|
+
EstimateSkeletonResponseSchema,
|
|
2730
|
+
await this.request("/estimate-skeleton", { method: "POST", body: JSON.stringify(body) }),
|
|
2731
|
+
"estimate-skeleton"
|
|
2732
|
+
);
|
|
2733
|
+
return { keypoints: res.keypoints, usage: res.usage };
|
|
2734
|
+
}
|
|
2600
2735
|
async getBackgroundJob(jobId) {
|
|
2601
2736
|
const raw = await this.request(`/background-jobs/${encodeURIComponent(jobId)}`);
|
|
2602
2737
|
return validateResponse(BackgroundJobSchema, raw, "background-jobs/{id}");
|
|
@@ -3331,6 +3466,9 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
3331
3466
|
lastFrameSha256: spec.revision.lastFrameSha256,
|
|
3332
3467
|
direction: spec.revision.direction,
|
|
3333
3468
|
enhancePrompt: spec.revision.enhancePrompt,
|
|
3469
|
+
keypointsSha256: spec.revision.keypointsSha256,
|
|
3470
|
+
skeletonTemplate: spec.revision.skeletonTemplate,
|
|
3471
|
+
description: spec.revision.description,
|
|
3334
3472
|
engine: spec.revision.engine
|
|
3335
3473
|
} : void 0
|
|
3336
3474
|
})
|
|
@@ -3419,6 +3557,18 @@ function objectProCost(spec) {
|
|
|
3419
3557
|
const south = object.reference;
|
|
3420
3558
|
return south ? proFlashObjectCost(south.width, south.height, object.directions, true) : proFlashObjectCost(spec.width, spec.height, object.directions, false);
|
|
3421
3559
|
}
|
|
3560
|
+
function animateSkeletonCost(frames) {
|
|
3561
|
+
const anchors = [[3, 2], [8, 3], [15, 4]];
|
|
3562
|
+
for (let i = 0; i < anchors.length - 1; i++) {
|
|
3563
|
+
const [lowFrames, lowCost] = anchors[i];
|
|
3564
|
+
const [highFrames, highCost] = anchors[i + 1];
|
|
3565
|
+
if (frames >= lowFrames && frames <= highFrames) {
|
|
3566
|
+
const t = (frames - lowFrames) / (highFrames - lowFrames);
|
|
3567
|
+
return lowCost + t * (highCost - lowCost);
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
return frames <= anchors[0][0] ? anchors[0][1] : anchors[anchors.length - 1][1];
|
|
3571
|
+
}
|
|
3422
3572
|
var CHARACTER_TEMPLATES = ["mannequin", "bear", "cat", "dog", "horse", "lion"];
|
|
3423
3573
|
var PRO_FLASH_TEMPLATES = [...CHARACTER_TEMPLATES, "custom"];
|
|
3424
3574
|
function encodeAnimationJob(job) {
|
|
@@ -3477,7 +3627,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3477
3627
|
* rather than a described edit — and `animate`/`animate-pixminimax`
|
|
3478
3628
|
* (`/animate-with-text-v3`, `/animate-pixminimax`), which animate any loose
|
|
3479
3629
|
* image from a text description with no character/object resource
|
|
3480
|
-
* required —
|
|
3630
|
+
* required — `animate-skeleton` (`/animate-with-skeleton-v3`, posing the
|
|
3631
|
+
* source from a supplied per-frame skeleton instead of a text description)
|
|
3632
|
+
* — and `interpolate` (`/interpolation-v2`, the in-betweens
|
|
3481
3633
|
* from one keyframe to another) and `edit-animation`
|
|
3482
3634
|
* (`/edit-animation-v2`, one text edit applied across a whole frame set).
|
|
3483
3635
|
* `outpaint` does not: there is no canvas-expansion endpoint in the API,
|
|
@@ -3485,7 +3637,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3485
3637
|
* outpaint path yet.
|
|
3486
3638
|
*/
|
|
3487
3639
|
supportsRevision(mode2) {
|
|
3488
|
-
return mode2 === "inpaint" || mode2 === "image-to-image" || mode2 === "reduce-colors" || mode2 === "correct-pixelart" || mode2 === "animate" || mode2 === "animate-pixminimax" || mode2 === "interpolate" || mode2 === "edit-animation";
|
|
3640
|
+
return mode2 === "inpaint" || mode2 === "image-to-image" || mode2 === "reduce-colors" || mode2 === "correct-pixelart" || mode2 === "animate" || mode2 === "animate-pixminimax" || mode2 === "animate-skeleton" || mode2 === "interpolate" || mode2 === "edit-animation";
|
|
3489
3641
|
}
|
|
3490
3642
|
/** PixelLab's own constraints: submissions must be >2s apart, and
|
|
3491
3643
|
* background jobs in flight are capped by subscription tier (Tier 1=8,
|
|
@@ -3516,6 +3668,10 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3516
3668
|
if (spec.revision?.mode === "reduce-colors" || spec.revision?.mode === "correct-pixelart") {
|
|
3517
3669
|
return { unit: "generations", amount: 0.1, candidates: 1 };
|
|
3518
3670
|
}
|
|
3671
|
+
if (spec.revision?.mode === "animate-skeleton") {
|
|
3672
|
+
const frames = spec.revision.frames ?? 8;
|
|
3673
|
+
return { unit: "generations", amount: Math.ceil(animateSkeletonCost(frames)), candidates: 1 };
|
|
3674
|
+
}
|
|
3519
3675
|
if (spec.revision?.mode === "interpolate" || spec.revision?.mode === "edit-animation") {
|
|
3520
3676
|
const width = spec.revision.sourceWidth ?? spec.width;
|
|
3521
3677
|
const height = spec.revision.sourceHeight ?? spec.height;
|
|
@@ -3597,6 +3753,18 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3597
3753
|
throw new Error(`PixelLab correct-pixelart source is ${width}x${height}; the API takes at most 1024 pixels per side`);
|
|
3598
3754
|
}
|
|
3599
3755
|
}
|
|
3756
|
+
if (spec.revision?.mode === "animate-skeleton") {
|
|
3757
|
+
const { sourceWidth: width, sourceHeight: height, frames, skeletonTemplate } = spec.revision;
|
|
3758
|
+
if (width != null && height != null && (width > 256 || height > 256)) {
|
|
3759
|
+
throw new Error(`PixelLab animate-skeleton source is ${width}x${height}; the API takes at most 256 pixels per side`);
|
|
3760
|
+
}
|
|
3761
|
+
if (frames != null && (frames < 3 || frames > 15)) {
|
|
3762
|
+
throw new Error(`PixelLab animate-skeleton takes 3 to 15 frames; the keypoints file has ${frames}`);
|
|
3763
|
+
}
|
|
3764
|
+
if (skeletonTemplate && !CHARACTER_TEMPLATES.includes(skeletonTemplate)) {
|
|
3765
|
+
throw new Error(`PixelLab animate-skeleton template "${skeletonTemplate}" is not one of ${CHARACTER_TEMPLATES.join(", ")}`);
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3600
3768
|
if (spec.revision?.mode === "animate" || spec.revision?.mode === "animate-pixminimax") {
|
|
3601
3769
|
const { sourceWidth: width, sourceHeight: height, mode: mode2, frames, lastFrameWidth, lastFrameHeight } = spec.revision;
|
|
3602
3770
|
if (width != null && height != null && (width > 256 || height > 256)) {
|
|
@@ -4746,6 +4914,27 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4746
4914
|
});
|
|
4747
4915
|
return { jobId: res2.background_job_id };
|
|
4748
4916
|
}
|
|
4917
|
+
if (revision.mode === "animate-skeleton") {
|
|
4918
|
+
if (!revision.keypointsFile || !revision.keypointsSha256 || !revision.skeleton) {
|
|
4919
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision keypoints are not ready`);
|
|
4920
|
+
}
|
|
4921
|
+
const keypointsBytes = readFileSync(revision.keypointsFile);
|
|
4922
|
+
if (sha256(keypointsBytes) !== revision.keypointsSha256) {
|
|
4923
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision keypoints changed after the manifest was resolved`);
|
|
4924
|
+
}
|
|
4925
|
+
const res2 = await this.client.animateWithSkeletonV3({
|
|
4926
|
+
firstFrame: image,
|
|
4927
|
+
firstFrameKeypoints: revision.skeleton.firstFrameKeypoints,
|
|
4928
|
+
keypoints: revision.skeleton.frames,
|
|
4929
|
+
direction: revision.direction,
|
|
4930
|
+
templateId: revision.skeletonTemplate,
|
|
4931
|
+
action: spec.prompt,
|
|
4932
|
+
description: revision.description,
|
|
4933
|
+
seed: spec.seed,
|
|
4934
|
+
noBackground: spec.noBackground
|
|
4935
|
+
});
|
|
4936
|
+
return { jobId: res2.background_job_id };
|
|
4937
|
+
}
|
|
4749
4938
|
if (revision.strength != null) {
|
|
4750
4939
|
throw new Error(
|
|
4751
4940
|
`${spec.styleId}/${spec.assetId}: PixelLab image-to-image revisions take no strength; edit-images-v2 always applies the full instruction`
|
|
@@ -4811,7 +5000,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4811
5000
|
if (revisionMode === "reduce-colors" || revisionMode === "correct-pixelart") {
|
|
4812
5001
|
return this.pollCachedRevision(jobId, context);
|
|
4813
5002
|
}
|
|
4814
|
-
if (revisionMode === "animate" || revisionMode === "animate-pixminimax" || revisionMode === "interpolate" || revisionMode === "edit-animation") {
|
|
5003
|
+
if (revisionMode === "animate" || revisionMode === "animate-pixminimax" || revisionMode === "animate-skeleton" || revisionMode === "interpolate" || revisionMode === "edit-animation") {
|
|
4815
5004
|
return this.pollAnimateRevision(jobId, context);
|
|
4816
5005
|
}
|
|
4817
5006
|
if (context?.spec?.revision) return this.pollRevision(jobId);
|
|
@@ -6546,11 +6735,12 @@ var ComfyUIProvider = class _ComfyUIProvider {
|
|
|
6546
6735
|
/**
|
|
6547
6736
|
* Everything else resolves generically to whatever the user's own
|
|
6548
6737
|
* workflow does with `bindings.sourceImage`. The frame-set modes
|
|
6549
|
-
* (`animate`, `animate-pixminimax`, `
|
|
6550
|
-
* the exception: they produce an ordered frame set,
|
|
6551
|
-
* revision path always writes a single output image
|
|
6552
|
-
* below) — a real structural gap, not a missing
|
|
6553
|
-
* rejected here rather than only failing once
|
|
6738
|
+
* (`animate`, `animate-pixminimax`, `animate-skeleton`, `interpolate`,
|
|
6739
|
+
* `edit-animation`) are the exception: they produce an ordered frame set,
|
|
6740
|
+
* and this adapter's revision path always writes a single output image
|
|
6741
|
+
* (see `submit`/`fetch` below) — a real structural gap, not a missing
|
|
6742
|
+
* binding, so they are rejected here rather than only failing once
|
|
6743
|
+
* `validate` runs.
|
|
6554
6744
|
*/
|
|
6555
6745
|
supportsRevision(mode2) {
|
|
6556
6746
|
return !FRAME_SET_REVISION_MODES.includes(mode2);
|
|
@@ -8453,6 +8643,8 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8453
8643
|
const paletteImage = paletteImageFile ? await optionalRevisionImage(paletteImageFile, "revision palette image", "png") : null;
|
|
8454
8644
|
const lastFrameFile = asset.revision.lastFrame ? path5.resolve(root, asset.revision.lastFrame) : void 0;
|
|
8455
8645
|
const lastFrame = lastFrameFile ? await optionalRevisionImage(lastFrameFile, "revision last frame") : null;
|
|
8646
|
+
const keypointsFile = asset.revision.keypointsFile ? path5.resolve(root, asset.revision.keypointsFile) : void 0;
|
|
8647
|
+
const keypoints = keypointsFile ? await optionalSkeletonSet(keypointsFile) : null;
|
|
8456
8648
|
resolved.revision = {
|
|
8457
8649
|
mode: asset.revision.mode,
|
|
8458
8650
|
sourceAssetId: asset.revision.from,
|
|
@@ -8493,6 +8685,18 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8493
8685
|
} : {},
|
|
8494
8686
|
...asset.revision.direction ? { direction: asset.revision.direction } : {},
|
|
8495
8687
|
...asset.revision.enhancePrompt == null ? {} : { enhancePrompt: asset.revision.enhancePrompt },
|
|
8688
|
+
...keypointsFile ? {
|
|
8689
|
+
keypointsFile,
|
|
8690
|
+
keypointsSha256: keypoints?.hash ?? null,
|
|
8691
|
+
skeleton: keypoints?.skeleton ?? null,
|
|
8692
|
+
// The manifest's own `frames` field stays rejected for this
|
|
8693
|
+
// mode (superRefine, types.ts) — the real frame count comes
|
|
8694
|
+
// from the keypoints file once it exists, not a manifest
|
|
8695
|
+
// number, so plan can only know it once authored.
|
|
8696
|
+
...keypoints ? { frames: keypoints.skeleton.frames.length } : {}
|
|
8697
|
+
} : {},
|
|
8698
|
+
...asset.revision.skeletonTemplate ? { skeletonTemplate: asset.revision.skeletonTemplate } : {},
|
|
8699
|
+
...asset.revision.description ? { description: asset.revision.description } : {},
|
|
8496
8700
|
...asset.revision.engine ? { engine: asset.revision.engine } : {}
|
|
8497
8701
|
};
|
|
8498
8702
|
}
|
|
@@ -8614,6 +8818,17 @@ async function optionalRevisionImage(file, label, requiredFormat) {
|
|
|
8614
8818
|
}
|
|
8615
8819
|
return { hash: sha256(bytes), ...metadata };
|
|
8616
8820
|
}
|
|
8821
|
+
async function optionalSkeletonSet(file) {
|
|
8822
|
+
if (!existsSync4(file)) return null;
|
|
8823
|
+
const bytes = await readFile3(file);
|
|
8824
|
+
let json;
|
|
8825
|
+
try {
|
|
8826
|
+
json = JSON.parse(bytes.toString("utf8"));
|
|
8827
|
+
} catch (error) {
|
|
8828
|
+
throw new Error(`revision keypoints file ${file} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
8829
|
+
}
|
|
8830
|
+
return { hash: sha256(bytes), skeleton: parseSkeletonSet(json, file) };
|
|
8831
|
+
}
|
|
8617
8832
|
async function revisionSourceMembers(stem, label) {
|
|
8618
8833
|
if (existsSync4(stem)) return null;
|
|
8619
8834
|
const at = (role) => memberPath(stem, role, 0, 2, MediaType.PNG);
|
|
@@ -10736,47 +10951,47 @@ import path14 from "path";
|
|
|
10736
10951
|
import { existsSync as existsSync9 } from "fs";
|
|
10737
10952
|
import { readdir, readFile as readFile7 } from "fs/promises";
|
|
10738
10953
|
import { fileURLToPath } from "url";
|
|
10739
|
-
import { z as
|
|
10954
|
+
import { z as z4 } from "zod";
|
|
10740
10955
|
var SHA256_RE = /^[0-9a-f]{64}$/;
|
|
10741
10956
|
var RECIPE_ID_RE = /^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/;
|
|
10742
10957
|
var VERSION_RE = /^\d+\.\d+\.\d+$/;
|
|
10743
10958
|
var RECIPE_FILE = "pixelkiln.recipe.json";
|
|
10744
10959
|
var RECIPE_DIR_TOKEN = "{{recipeDir}}";
|
|
10745
|
-
var PortablePathSchema =
|
|
10960
|
+
var PortablePathSchema = z4.string().min(1).refine((value) => {
|
|
10746
10961
|
if (value.includes("\\") || path14.posix.isAbsolute(value)) return false;
|
|
10747
10962
|
const parts = value.split("/");
|
|
10748
10963
|
return !parts.includes("") && !parts.includes(".") && !parts.includes("..");
|
|
10749
10964
|
}, "expected a portable relative path without '.', '..', or backslashes");
|
|
10750
|
-
var RecipeBindingSchema =
|
|
10751
|
-
nodeId:
|
|
10752
|
-
input:
|
|
10965
|
+
var RecipeBindingSchema = z4.object({
|
|
10966
|
+
nodeId: z4.string().min(1),
|
|
10967
|
+
input: z4.string().min(1)
|
|
10753
10968
|
}).strict();
|
|
10754
|
-
var RecipeSchema =
|
|
10755
|
-
$schema:
|
|
10756
|
-
format:
|
|
10757
|
-
schemaVersion:
|
|
10758
|
-
id:
|
|
10759
|
-
version:
|
|
10760
|
-
provider:
|
|
10761
|
-
summary:
|
|
10762
|
-
files:
|
|
10969
|
+
var RecipeSchema = z4.object({
|
|
10970
|
+
$schema: z4.string().url().optional(),
|
|
10971
|
+
format: z4.literal("pixelkiln-recipe"),
|
|
10972
|
+
schemaVersion: z4.literal(1),
|
|
10973
|
+
id: z4.string().regex(RECIPE_ID_RE, "expected provider/name"),
|
|
10974
|
+
version: z4.string().regex(VERSION_RE, "expected x.y.z"),
|
|
10975
|
+
provider: z4.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
10976
|
+
summary: z4.string().min(1).max(240),
|
|
10977
|
+
files: z4.array(z4.object({
|
|
10763
10978
|
path: PortablePathSchema,
|
|
10764
|
-
role:
|
|
10765
|
-
sha256:
|
|
10979
|
+
role: z4.enum(["workflow", "reference"]),
|
|
10980
|
+
sha256: z4.string().regex(SHA256_RE)
|
|
10766
10981
|
}).strict()).default([]),
|
|
10767
|
-
models:
|
|
10982
|
+
models: z4.array(z4.object({
|
|
10768
10983
|
path: PortablePathSchema,
|
|
10769
|
-
sha256:
|
|
10770
|
-
source:
|
|
10771
|
-
license:
|
|
10984
|
+
sha256: z4.string().regex(SHA256_RE),
|
|
10985
|
+
source: z4.string().url(),
|
|
10986
|
+
license: z4.string().min(1)
|
|
10772
10987
|
}).strict()).default([]),
|
|
10773
|
-
styleId:
|
|
10988
|
+
styleId: z4.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
10774
10989
|
style: StyleSchema,
|
|
10775
|
-
workflow:
|
|
10990
|
+
workflow: z4.object({
|
|
10776
10991
|
path: PortablePathSchema,
|
|
10777
|
-
outputNodeId:
|
|
10778
|
-
numImages:
|
|
10779
|
-
bindings:
|
|
10992
|
+
outputNodeId: z4.string().min(1),
|
|
10993
|
+
numImages: z4.number().int().min(1).max(16),
|
|
10994
|
+
bindings: z4.object({
|
|
10780
10995
|
prompt: RecipeBindingSchema,
|
|
10781
10996
|
width: RecipeBindingSchema.optional(),
|
|
10782
10997
|
height: RecipeBindingSchema.optional(),
|
|
@@ -10787,67 +11002,67 @@ var RecipeSchema = z3.object({
|
|
|
10787
11002
|
strength: RecipeBindingSchema.optional()
|
|
10788
11003
|
}).strict()
|
|
10789
11004
|
}).strict().optional(),
|
|
10790
|
-
quality:
|
|
10791
|
-
stage:
|
|
10792
|
-
workingCanvas:
|
|
10793
|
-
width:
|
|
10794
|
-
height:
|
|
11005
|
+
quality: z4.object({
|
|
11006
|
+
stage: z4.enum(["composition-source", "production-candidate"]),
|
|
11007
|
+
workingCanvas: z4.object({
|
|
11008
|
+
width: z4.number().int().min(16),
|
|
11009
|
+
height: z4.number().int().min(16)
|
|
10795
11010
|
}).strict(),
|
|
10796
|
-
recommendedNativeSize:
|
|
10797
|
-
min:
|
|
10798
|
-
max:
|
|
11011
|
+
recommendedNativeSize: z4.object({
|
|
11012
|
+
min: z4.number().int().min(1),
|
|
11013
|
+
max: z4.number().int().min(1)
|
|
10799
11014
|
}).strict(),
|
|
10800
|
-
paletteColors:
|
|
10801
|
-
min:
|
|
10802
|
-
max:
|
|
11015
|
+
paletteColors: z4.object({
|
|
11016
|
+
min: z4.number().int().min(1),
|
|
11017
|
+
max: z4.number().int().min(1)
|
|
10803
11018
|
}).strict(),
|
|
10804
|
-
background:
|
|
10805
|
-
checks:
|
|
11019
|
+
background: z4.enum(["opaque", "transparent", "full-bleed"]),
|
|
11020
|
+
checks: z4.array(z4.enum([
|
|
10806
11021
|
"prompt-coverage",
|
|
10807
11022
|
"native-grid",
|
|
10808
11023
|
"final-palette",
|
|
10809
11024
|
"alpha-edge",
|
|
10810
11025
|
"human-1x"
|
|
10811
11026
|
])).min(1),
|
|
10812
|
-
notes:
|
|
11027
|
+
notes: z4.array(z4.string().min(1)).default([])
|
|
10813
11028
|
}).strict(),
|
|
10814
|
-
integrity:
|
|
10815
|
-
algorithm:
|
|
10816
|
-
digest:
|
|
11029
|
+
integrity: z4.object({
|
|
11030
|
+
algorithm: z4.literal("sha256"),
|
|
11031
|
+
digest: z4.string().regex(SHA256_RE)
|
|
10817
11032
|
}).strict()
|
|
10818
11033
|
}).strict().superRefine((recipe, context) => {
|
|
10819
11034
|
if (recipe.style.provider && recipe.style.provider !== recipe.provider) {
|
|
10820
11035
|
context.addIssue({
|
|
10821
|
-
code:
|
|
11036
|
+
code: z4.ZodIssueCode.custom,
|
|
10822
11037
|
path: ["style", "provider"],
|
|
10823
11038
|
message: "must match the recipe provider"
|
|
10824
11039
|
});
|
|
10825
11040
|
}
|
|
10826
11041
|
const filePaths = recipe.files.map((file) => file.path);
|
|
10827
11042
|
if (new Set(filePaths).size !== filePaths.length) {
|
|
10828
|
-
context.addIssue({ code:
|
|
11043
|
+
context.addIssue({ code: z4.ZodIssueCode.custom, path: ["files"], message: "duplicate file path" });
|
|
10829
11044
|
}
|
|
10830
11045
|
const modelPaths = recipe.models.map((model) => model.path);
|
|
10831
11046
|
if (new Set(modelPaths).size !== modelPaths.length) {
|
|
10832
|
-
context.addIssue({ code:
|
|
11047
|
+
context.addIssue({ code: z4.ZodIssueCode.custom, path: ["models"], message: "duplicate model path" });
|
|
10833
11048
|
}
|
|
10834
11049
|
if (filePaths.includes(RECIPE_FILE)) {
|
|
10835
11050
|
context.addIssue({
|
|
10836
|
-
code:
|
|
11051
|
+
code: z4.ZodIssueCode.custom,
|
|
10837
11052
|
path: ["files"],
|
|
10838
11053
|
message: `${RECIPE_FILE} cannot hash itself`
|
|
10839
11054
|
});
|
|
10840
11055
|
}
|
|
10841
11056
|
if (recipe.quality.recommendedNativeSize.min > recipe.quality.recommendedNativeSize.max) {
|
|
10842
11057
|
context.addIssue({
|
|
10843
|
-
code:
|
|
11058
|
+
code: z4.ZodIssueCode.custom,
|
|
10844
11059
|
path: ["quality", "recommendedNativeSize"],
|
|
10845
11060
|
message: "min cannot exceed max"
|
|
10846
11061
|
});
|
|
10847
11062
|
}
|
|
10848
11063
|
if (recipe.quality.paletteColors.min > recipe.quality.paletteColors.max) {
|
|
10849
11064
|
context.addIssue({
|
|
10850
|
-
code:
|
|
11065
|
+
code: z4.ZodIssueCode.custom,
|
|
10851
11066
|
path: ["quality", "paletteColors"],
|
|
10852
11067
|
message: "min cannot exceed max"
|
|
10853
11068
|
});
|
|
@@ -10856,7 +11071,7 @@ var RecipeSchema = z3.object({
|
|
|
10856
11071
|
(file) => file.path === recipe.workflow.path && file.role === "workflow"
|
|
10857
11072
|
)) {
|
|
10858
11073
|
context.addIssue({
|
|
10859
|
-
code:
|
|
11074
|
+
code: z4.ZodIssueCode.custom,
|
|
10860
11075
|
path: ["workflow", "path"],
|
|
10861
11076
|
message: "must name a file whose role is workflow"
|
|
10862
11077
|
});
|
|
@@ -10864,7 +11079,7 @@ var RecipeSchema = z3.object({
|
|
|
10864
11079
|
if (recipe.provider === "comfyui") {
|
|
10865
11080
|
if (!recipe.workflow) {
|
|
10866
11081
|
context.addIssue({
|
|
10867
|
-
code:
|
|
11082
|
+
code: z4.ZodIssueCode.custom,
|
|
10868
11083
|
path: ["workflow"],
|
|
10869
11084
|
message: "ComfyUI recipes require workflow metadata"
|
|
10870
11085
|
});
|
|
@@ -10873,7 +11088,7 @@ var RecipeSchema = z3.object({
|
|
|
10873
11088
|
const options = recipe.style.providerOptions.comfyui;
|
|
10874
11089
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
10875
11090
|
context.addIssue({
|
|
10876
|
-
code:
|
|
11091
|
+
code: z4.ZodIssueCode.custom,
|
|
10877
11092
|
path: ["style", "providerOptions", "comfyui"],
|
|
10878
11093
|
message: "ComfyUI recipes require ComfyUI provider options"
|
|
10879
11094
|
});
|
|
@@ -10887,7 +11102,7 @@ var RecipeSchema = z3.object({
|
|
|
10887
11102
|
};
|
|
10888
11103
|
if (JSON.stringify(canonical3(options)) !== JSON.stringify(canonical3(expected))) {
|
|
10889
11104
|
context.addIssue({
|
|
10890
|
-
code:
|
|
11105
|
+
code: z4.ZodIssueCode.custom,
|
|
10891
11106
|
path: ["style", "providerOptions", "comfyui"],
|
|
10892
11107
|
message: "must match workflow metadata and use {{recipeDir}} for workflowFile"
|
|
10893
11108
|
});
|
|
@@ -11325,11 +11540,11 @@ async function generateFont(client2, opts) {
|
|
|
11325
11540
|
import path17 from "path";
|
|
11326
11541
|
import { existsSync as existsSync12 } from "fs";
|
|
11327
11542
|
import { readFile as readFile10 } from "fs/promises";
|
|
11328
|
-
import { z as
|
|
11543
|
+
import { z as z5 } from "zod";
|
|
11329
11544
|
var SHA256_RE2 = /^[0-9a-f]{64}$/;
|
|
11330
11545
|
var HEX_RE = /^#[0-9a-f]{6}$/;
|
|
11331
11546
|
var MAX_REDMEAN_DISTANCE = 765;
|
|
11332
|
-
var QualityPathSchema =
|
|
11547
|
+
var QualityPathSchema = z5.string().min(1).refine(
|
|
11333
11548
|
(value) => !path17.posix.isAbsolute(value) && !value.includes("\\"),
|
|
11334
11549
|
"expected a portable relative path"
|
|
11335
11550
|
);
|
|
@@ -11343,53 +11558,53 @@ var DEFAULT_QUALITY_TOLERANCES = {
|
|
|
11343
11558
|
maxEdgeContrastDrop: 0.03,
|
|
11344
11559
|
maxIsolatedPixelIncrease: 5e-3
|
|
11345
11560
|
};
|
|
11346
|
-
var QualityToleranceSchema =
|
|
11347
|
-
requireExactHash:
|
|
11348
|
-
maxColorCountIncrease:
|
|
11349
|
-
maxNewColors:
|
|
11350
|
-
maxTransparencyDelta:
|
|
11351
|
-
maxPartialAlphaIncrease:
|
|
11352
|
-
maxEdgeDensityDelta:
|
|
11353
|
-
maxEdgeContrastDrop:
|
|
11354
|
-
maxIsolatedPixelIncrease:
|
|
11561
|
+
var QualityToleranceSchema = z5.object({
|
|
11562
|
+
requireExactHash: z5.boolean(),
|
|
11563
|
+
maxColorCountIncrease: z5.number().int().min(0),
|
|
11564
|
+
maxNewColors: z5.number().int().min(0),
|
|
11565
|
+
maxTransparencyDelta: z5.number().min(0).max(1),
|
|
11566
|
+
maxPartialAlphaIncrease: z5.number().min(0).max(1),
|
|
11567
|
+
maxEdgeDensityDelta: z5.number().min(0).max(1),
|
|
11568
|
+
maxEdgeContrastDrop: z5.number().min(0).max(1),
|
|
11569
|
+
maxIsolatedPixelIncrease: z5.number().min(0).max(1)
|
|
11355
11570
|
}).strict();
|
|
11356
|
-
var ImageQualityMetricsSchema =
|
|
11357
|
-
sha256:
|
|
11358
|
-
width:
|
|
11359
|
-
height:
|
|
11360
|
-
colorCount:
|
|
11361
|
-
colors:
|
|
11362
|
-
transparency:
|
|
11363
|
-
partialAlpha:
|
|
11364
|
-
edgeDensity:
|
|
11365
|
-
meanEdgeContrast:
|
|
11366
|
-
isolatedPixelRatio:
|
|
11571
|
+
var ImageQualityMetricsSchema = z5.object({
|
|
11572
|
+
sha256: z5.string().regex(SHA256_RE2),
|
|
11573
|
+
width: z5.number().int().min(1),
|
|
11574
|
+
height: z5.number().int().min(1),
|
|
11575
|
+
colorCount: z5.number().int().min(0),
|
|
11576
|
+
colors: z5.array(z5.string().regex(HEX_RE)),
|
|
11577
|
+
transparency: z5.number().min(0).max(1),
|
|
11578
|
+
partialAlpha: z5.number().min(0).max(1),
|
|
11579
|
+
edgeDensity: z5.number().min(0).max(1),
|
|
11580
|
+
meanEdgeContrast: z5.number().min(0).max(1),
|
|
11581
|
+
isolatedPixelRatio: z5.number().min(0).max(1)
|
|
11367
11582
|
}).strict();
|
|
11368
|
-
var QualityBaselineCaseSchema =
|
|
11369
|
-
id:
|
|
11583
|
+
var QualityBaselineCaseSchema = z5.object({
|
|
11584
|
+
id: z5.string().regex(/^[a-z0-9][a-z0-9/_-]*$/),
|
|
11370
11585
|
file: QualityPathSchema,
|
|
11371
|
-
record:
|
|
11586
|
+
record: z5.object({
|
|
11372
11587
|
path: QualityPathSchema,
|
|
11373
|
-
sha256:
|
|
11588
|
+
sha256: z5.string().regex(SHA256_RE2)
|
|
11374
11589
|
}).strict().optional(),
|
|
11375
11590
|
expected: ImageQualityMetricsSchema,
|
|
11376
11591
|
tolerances: QualityToleranceSchema
|
|
11377
11592
|
}).strict();
|
|
11378
|
-
var QualityBaselineSchema =
|
|
11379
|
-
$schema:
|
|
11380
|
-
format:
|
|
11381
|
-
schemaVersion:
|
|
11382
|
-
cases:
|
|
11593
|
+
var QualityBaselineSchema = z5.object({
|
|
11594
|
+
$schema: z5.string().url().optional(),
|
|
11595
|
+
format: z5.literal("pixelkiln-quality-baseline"),
|
|
11596
|
+
schemaVersion: z5.literal(1),
|
|
11597
|
+
cases: z5.array(QualityBaselineCaseSchema).min(1)
|
|
11383
11598
|
}).strict().superRefine((baseline, context) => {
|
|
11384
11599
|
const ids = baseline.cases.map((entry) => entry.id);
|
|
11385
11600
|
if (new Set(ids).size !== ids.length) {
|
|
11386
|
-
context.addIssue({ code:
|
|
11601
|
+
context.addIssue({ code: z5.ZodIssueCode.custom, path: ["cases"], message: "duplicate case id" });
|
|
11387
11602
|
}
|
|
11388
11603
|
});
|
|
11389
|
-
var QualityInputSchema =
|
|
11390
|
-
id:
|
|
11391
|
-
path:
|
|
11392
|
-
record:
|
|
11604
|
+
var QualityInputSchema = z5.object({
|
|
11605
|
+
id: z5.string().regex(/^[a-z0-9][a-z0-9/_-]*$/),
|
|
11606
|
+
path: z5.string().min(1),
|
|
11607
|
+
record: z5.string().min(1).optional(),
|
|
11393
11608
|
tolerances: QualityToleranceSchema.partial().optional()
|
|
11394
11609
|
}).strict();
|
|
11395
11610
|
function message4(error) {
|
|
@@ -11491,7 +11706,7 @@ async function measureImageQuality(file) {
|
|
|
11491
11706
|
}
|
|
11492
11707
|
}
|
|
11493
11708
|
function resolveQualityInputs(raw, inputsFilePath) {
|
|
11494
|
-
const parsed =
|
|
11709
|
+
const parsed = z5.array(QualityInputSchema).min(1).safeParse(raw);
|
|
11495
11710
|
if (!parsed.success) {
|
|
11496
11711
|
throw new Error(
|
|
11497
11712
|
"--inputs must be a non-empty JSON array of quality cases:\n" + parsed.error.issues.map((issue) => ` ${issue.path.join(".") || "$"}: ${issue.message}`).join("\n")
|
|
@@ -11714,11 +11929,11 @@ import path20 from "path";
|
|
|
11714
11929
|
import { mkdir as mkdir5, readFile as readFile11, rename as rename4, rm as rm4, writeFile as writeFile5 } from "fs/promises";
|
|
11715
11930
|
import { existsSync as existsSync13 } from "fs";
|
|
11716
11931
|
import pathModule from "path";
|
|
11717
|
-
import { z as
|
|
11718
|
-
var HashCacheSchema =
|
|
11719
|
-
version:
|
|
11932
|
+
import { z as z6 } from "zod";
|
|
11933
|
+
var HashCacheSchema = z6.object({
|
|
11934
|
+
version: z6.literal(1),
|
|
11720
11935
|
/** objectId → sha256 of that object's image bytes. */
|
|
11721
|
-
hashes:
|
|
11936
|
+
hashes: z6.record(z6.string())
|
|
11722
11937
|
});
|
|
11723
11938
|
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
11724
11939
|
function isSha256Hash(value) {
|
|
@@ -13266,6 +13481,9 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13266
13481
|
...spec.revision.lastFrameSha256 ? { lastFrameSha256: spec.revision.lastFrameSha256 } : {},
|
|
13267
13482
|
...spec.revision.direction ? { direction: spec.revision.direction } : {},
|
|
13268
13483
|
...spec.revision.enhancePrompt == null ? {} : { enhancePrompt: spec.revision.enhancePrompt },
|
|
13484
|
+
...spec.revision.keypointsSha256 ? { keypointsSha256: spec.revision.keypointsSha256 } : {},
|
|
13485
|
+
...spec.revision.skeletonTemplate ? { skeletonTemplate: spec.revision.skeletonTemplate } : {},
|
|
13486
|
+
...spec.revision.description ? { description: spec.revision.description } : {},
|
|
13269
13487
|
...spec.revision.engine ? { engine: spec.revision.engine } : {}
|
|
13270
13488
|
} : null,
|
|
13271
13489
|
outfit: spec.character?.kind === "outfit" && outfitParentEntry ? {
|
|
@@ -14563,20 +14781,20 @@ import path29 from "path";
|
|
|
14563
14781
|
import { mkdir as mkdir7, readFile as readFile18, rename as rename6, rm as rm7, writeFile as writeFile9 } from "fs/promises";
|
|
14564
14782
|
import { existsSync as existsSync21 } from "fs";
|
|
14565
14783
|
import path25 from "path";
|
|
14566
|
-
import { z as
|
|
14567
|
-
var WorkspaceProjectSchema =
|
|
14568
|
-
id:
|
|
14784
|
+
import { z as z7 } from "zod";
|
|
14785
|
+
var WorkspaceProjectSchema = z7.object({
|
|
14786
|
+
id: z7.string().min(1),
|
|
14569
14787
|
/** Manifest path, relative to the catalog file's own directory. */
|
|
14570
|
-
manifest:
|
|
14788
|
+
manifest: z7.string().min(1),
|
|
14571
14789
|
/** Lockfile path, relative to the catalog file's own directory. */
|
|
14572
|
-
lock:
|
|
14573
|
-
provider:
|
|
14790
|
+
lock: z7.string().min(1),
|
|
14791
|
+
provider: z7.string().min(1).default("pixellab"),
|
|
14574
14792
|
/** Free-form label for a shared account, e.g. distinguishing sandboxes. */
|
|
14575
|
-
account:
|
|
14793
|
+
account: z7.string().optional()
|
|
14576
14794
|
}).strict();
|
|
14577
|
-
var WorkspaceSchema =
|
|
14578
|
-
version:
|
|
14579
|
-
projects:
|
|
14795
|
+
var WorkspaceSchema = z7.object({
|
|
14796
|
+
version: z7.literal(1),
|
|
14797
|
+
projects: z7.array(WorkspaceProjectSchema).default([])
|
|
14580
14798
|
}).strict();
|
|
14581
14799
|
function parseWorkspace(raw) {
|
|
14582
14800
|
const parsed = WorkspaceSchema.safeParse(raw);
|
|
@@ -14694,62 +14912,62 @@ function validateWorkspace(ws, dir) {
|
|
|
14694
14912
|
|
|
14695
14913
|
// src/gallery/edit.ts
|
|
14696
14914
|
import path28 from "path";
|
|
14697
|
-
import { z as
|
|
14915
|
+
import { z as z10 } from "zod";
|
|
14698
14916
|
|
|
14699
14917
|
// src/manifest-edit.ts
|
|
14700
14918
|
import { readFile as readFile19, rename as rename7, rm as rm8, writeFile as writeFile10 } from "fs/promises";
|
|
14701
14919
|
import path26 from "path";
|
|
14702
|
-
import { z as
|
|
14703
|
-
var HexSha =
|
|
14704
|
-
var AssetPatchSchema =
|
|
14705
|
-
prompt:
|
|
14920
|
+
import { z as z8 } from "zod";
|
|
14921
|
+
var HexSha = z8.string().regex(/^[0-9a-f]{64}$/);
|
|
14922
|
+
var AssetPatchSchema = z8.object({
|
|
14923
|
+
prompt: z8.string().optional(),
|
|
14706
14924
|
/** Per-style override for the style being viewed; null removes it. */
|
|
14707
|
-
promptForStyle:
|
|
14708
|
-
category:
|
|
14709
|
-
width:
|
|
14710
|
-
height:
|
|
14711
|
-
size:
|
|
14712
|
-
tags:
|
|
14925
|
+
promptForStyle: z8.object({ styleId: z8.string().min(1), prompt: z8.string().nullable() }).optional(),
|
|
14926
|
+
category: z8.string().nullable().optional(),
|
|
14927
|
+
width: z8.number().int().nullable().optional(),
|
|
14928
|
+
height: z8.number().int().nullable().optional(),
|
|
14929
|
+
size: z8.number().int().nullable().optional(),
|
|
14930
|
+
tags: z8.array(z8.string()).optional()
|
|
14713
14931
|
}).strict();
|
|
14714
|
-
var NewStateSchema =
|
|
14932
|
+
var NewStateSchema = z8.object({
|
|
14715
14933
|
/** Asset id of the parent this states; must already exist. */
|
|
14716
|
-
of:
|
|
14717
|
-
paletteFromReference:
|
|
14718
|
-
canvas:
|
|
14934
|
+
of: z8.string().min(1),
|
|
14935
|
+
paletteFromReference: z8.boolean().optional(),
|
|
14936
|
+
canvas: z8.object({ width: z8.number().int().min(16).max(256), height: z8.number().int().min(16).max(256) }).strict().optional()
|
|
14719
14937
|
}).strict();
|
|
14720
|
-
var NewAnimationSchema =
|
|
14938
|
+
var NewAnimationSchema = z8.object({
|
|
14721
14939
|
/** Asset id of the parent this animates; must already exist. */
|
|
14722
|
-
of:
|
|
14940
|
+
of: z8.string().min(1),
|
|
14723
14941
|
/** A PixelLab template id (`character` only; `objectPro` has no template concept). */
|
|
14724
|
-
template:
|
|
14942
|
+
template: z8.string().min(1).optional(),
|
|
14725
14943
|
direction: CharacterDirectionSchema.optional(),
|
|
14726
|
-
frames:
|
|
14727
|
-
fps:
|
|
14944
|
+
frames: z8.number().int().min(4).max(16).optional(),
|
|
14945
|
+
fps: z8.number().int().min(1).max(60).optional(),
|
|
14728
14946
|
mode: CharacterAnimationModeSchema.optional(),
|
|
14729
14947
|
/** What is being animated, when the parent's own description would mislead the model (`character` only). */
|
|
14730
|
-
subject:
|
|
14731
|
-
enhancePrompt:
|
|
14948
|
+
subject: z8.string().min(1).optional(),
|
|
14949
|
+
enhancePrompt: z8.boolean().optional()
|
|
14732
14950
|
}).strict();
|
|
14733
|
-
var NewAssetSchema =
|
|
14734
|
-
prompt:
|
|
14735
|
-
category:
|
|
14736
|
-
width:
|
|
14737
|
-
height:
|
|
14738
|
-
size:
|
|
14739
|
-
tags:
|
|
14951
|
+
var NewAssetSchema = z8.object({
|
|
14952
|
+
prompt: z8.string(),
|
|
14953
|
+
category: z8.string().optional(),
|
|
14954
|
+
width: z8.number().int().optional(),
|
|
14955
|
+
height: z8.number().int().optional(),
|
|
14956
|
+
size: z8.number().int().optional(),
|
|
14957
|
+
tags: z8.array(z8.string()).optional(),
|
|
14740
14958
|
/** Restrict to these styles; empty or omitted means every style. */
|
|
14741
|
-
styles:
|
|
14959
|
+
styles: z8.array(z8.string().min(1)).optional(),
|
|
14742
14960
|
/**
|
|
14743
14961
|
* A controlled regeneration of another asset in the same manifest,
|
|
14744
14962
|
* instead of a fresh generation. `inpaint` needs a mask upload the
|
|
14745
14963
|
* gallery does not offer yet, so only `image-to-image` can be created
|
|
14746
14964
|
* here; hand-edit the manifest for the other modes.
|
|
14747
14965
|
*/
|
|
14748
|
-
revision:
|
|
14749
|
-
mode:
|
|
14966
|
+
revision: z8.object({
|
|
14967
|
+
mode: z8.literal("image-to-image"),
|
|
14750
14968
|
/** Asset id of the parent this revises; must already exist. */
|
|
14751
|
-
from:
|
|
14752
|
-
strength:
|
|
14969
|
+
from: z8.string().min(1),
|
|
14970
|
+
strength: z8.number().min(0).max(1).optional()
|
|
14753
14971
|
}).strict().optional(),
|
|
14754
14972
|
/** A pose or outfit of an existing `character`/`objectPro` base or state. */
|
|
14755
14973
|
state: NewStateSchema.optional(),
|
|
@@ -14765,58 +14983,58 @@ var CANDIDATE_OPTION = {
|
|
|
14765
14983
|
comfyui: "numImages",
|
|
14766
14984
|
scenario: "numOutputs"
|
|
14767
14985
|
};
|
|
14768
|
-
var ManifestEditSchema =
|
|
14769
|
-
|
|
14770
|
-
action:
|
|
14986
|
+
var ManifestEditSchema = z8.discriminatedUnion("action", [
|
|
14987
|
+
z8.object({
|
|
14988
|
+
action: z8.literal("patch-asset"),
|
|
14771
14989
|
/** Workspace project id; omitted for a single-project gallery. */
|
|
14772
|
-
project:
|
|
14773
|
-
assetId:
|
|
14990
|
+
project: z8.string().min(1).optional(),
|
|
14991
|
+
assetId: z8.string().min(1),
|
|
14774
14992
|
/** Manifest bytes the page last saw; a mismatch refuses the write. */
|
|
14775
14993
|
expectedSha256: HexSha,
|
|
14776
14994
|
patch: AssetPatchSchema
|
|
14777
14995
|
}).strict(),
|
|
14778
|
-
|
|
14779
|
-
action:
|
|
14780
|
-
project:
|
|
14781
|
-
assetId:
|
|
14996
|
+
z8.object({
|
|
14997
|
+
action: z8.literal("add-asset"),
|
|
14998
|
+
project: z8.string().min(1).optional(),
|
|
14999
|
+
assetId: z8.string().min(1).regex(/^[^/\\]+$/, "asset ids cannot contain slashes"),
|
|
14782
15000
|
expectedSha256: HexSha,
|
|
14783
15001
|
asset: NewAssetSchema
|
|
14784
15002
|
}).strict(),
|
|
14785
|
-
|
|
14786
|
-
action:
|
|
14787
|
-
project:
|
|
14788
|
-
assetId:
|
|
14789
|
-
styleId:
|
|
15003
|
+
z8.object({
|
|
15004
|
+
action: z8.literal("set-source"),
|
|
15005
|
+
project: z8.string().min(1).optional(),
|
|
15006
|
+
assetId: z8.string().min(1),
|
|
15007
|
+
styleId: z8.string().min(1),
|
|
14790
15008
|
/** Manifest-relative path of the art that stands in for this asset in this style. */
|
|
14791
|
-
source:
|
|
15009
|
+
source: z8.string().min(1),
|
|
14792
15010
|
expectedSha256: HexSha
|
|
14793
15011
|
}).strict(),
|
|
14794
|
-
|
|
14795
|
-
action:
|
|
14796
|
-
project:
|
|
14797
|
-
assetId:
|
|
14798
|
-
styleId:
|
|
15012
|
+
z8.object({
|
|
15013
|
+
action: z8.literal("clear-source"),
|
|
15014
|
+
project: z8.string().min(1).optional(),
|
|
15015
|
+
assetId: z8.string().min(1),
|
|
15016
|
+
styleId: z8.string().min(1),
|
|
14799
15017
|
expectedSha256: HexSha
|
|
14800
15018
|
}).strict(),
|
|
14801
|
-
|
|
14802
|
-
action:
|
|
14803
|
-
project:
|
|
14804
|
-
styleId:
|
|
15019
|
+
z8.object({
|
|
15020
|
+
action: z8.literal("patch-style"),
|
|
15021
|
+
project: z8.string().min(1).optional(),
|
|
15022
|
+
styleId: z8.string().min(1),
|
|
14805
15023
|
expectedSha256: HexSha,
|
|
14806
|
-
patch:
|
|
15024
|
+
patch: z8.object({
|
|
14807
15025
|
/** Candidates per generation, written to the provider's own option. */
|
|
14808
|
-
candidates:
|
|
15026
|
+
candidates: z8.number().int().min(1).max(64).optional(),
|
|
14809
15027
|
/** Empty clears the style's own value (inherit, or the default). */
|
|
14810
|
-
promptPrefix:
|
|
14811
|
-
promptSuffix:
|
|
15028
|
+
promptPrefix: z8.string().optional(),
|
|
15029
|
+
promptSuffix: z8.string().optional(),
|
|
14812
15030
|
/** `#rrggbb` values; null or empty clears the style's own palette. */
|
|
14813
|
-
palette:
|
|
15031
|
+
palette: z8.array(z8.string().regex(/^#?[0-9a-f]{6}$/i, "expected a six-digit hex colour")).max(256).nullable().optional(),
|
|
14814
15032
|
/** Snap downloaded art to the palette; false clears the style's own value. */
|
|
14815
|
-
enforcePalette:
|
|
15033
|
+
enforcePalette: z8.boolean().optional(),
|
|
14816
15034
|
/** Provider view name (PixelLab: low top-down, high top-down, side); empty clears. */
|
|
14817
|
-
view:
|
|
15035
|
+
view: z8.string().max(64).nullable().optional(),
|
|
14818
15036
|
/** pixflux only; null clears the style's own value. */
|
|
14819
|
-
noBackground:
|
|
15037
|
+
noBackground: z8.boolean().nullable().optional()
|
|
14820
15038
|
}).strict().refine((patch) => Object.keys(patch).length > 0, { message: "nothing to change" })
|
|
14821
15039
|
}).strict()
|
|
14822
15040
|
]);
|
|
@@ -15010,7 +15228,7 @@ async function applyManifestEdit(manifestPath, edit) {
|
|
|
15010
15228
|
import { existsSync as existsSync22 } from "fs";
|
|
15011
15229
|
import { copyFile, mkdir as mkdir8, readFile as readFile20, rename as rename8, rm as rm9, writeFile as writeFile11 } from "fs/promises";
|
|
15012
15230
|
import path27 from "path";
|
|
15013
|
-
import { z as
|
|
15231
|
+
import { z as z9 } from "zod";
|
|
15014
15232
|
var HAND_EDIT_DIR = "edits";
|
|
15015
15233
|
function handEditPath(loaded, spec) {
|
|
15016
15234
|
const style = loaded.manifest.styles[spec.styleId];
|
|
@@ -15107,35 +15325,35 @@ async function detachHandEdit(loaded, spec, opts = {}) {
|
|
|
15107
15325
|
});
|
|
15108
15326
|
return { manifestSha256: result.sha256, changed: result.changed };
|
|
15109
15327
|
}
|
|
15110
|
-
var CompanionOutputSchema =
|
|
15328
|
+
var CompanionOutputSchema = z9.object({
|
|
15111
15329
|
/** Output role for a set member; null for a single image. */
|
|
15112
|
-
role:
|
|
15330
|
+
role: z9.string().nullable(),
|
|
15113
15331
|
/** sha256 of the generated file this member started from; null when it started from untracked art. */
|
|
15114
|
-
basedOn:
|
|
15332
|
+
basedOn: z9.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
15115
15333
|
/** sha256 of the member as saved, so a later change by another tool is visible. */
|
|
15116
|
-
sha256:
|
|
15334
|
+
sha256: z9.string().regex(/^[0-9a-f]{64}$/)
|
|
15117
15335
|
}).strict();
|
|
15118
|
-
var CompanionV2Schema =
|
|
15119
|
-
version:
|
|
15336
|
+
var CompanionV2Schema = z9.object({
|
|
15337
|
+
version: z9.literal(2),
|
|
15120
15338
|
/** Editor identity the bridge reported, e.g. `pixelorama@v1.2.2-stable`. */
|
|
15121
|
-
editor:
|
|
15122
|
-
protocol:
|
|
15123
|
-
savedAt:
|
|
15339
|
+
editor: z9.string().min(1),
|
|
15340
|
+
protocol: z9.number().int().positive(),
|
|
15341
|
+
savedAt: z9.string().datetime(),
|
|
15124
15342
|
/** Basename of the layered project file beside the edit, when one was kept. */
|
|
15125
|
-
project:
|
|
15343
|
+
project: z9.string().min(1).nullable(),
|
|
15126
15344
|
/** One entry per file, in output order. */
|
|
15127
|
-
outputs:
|
|
15345
|
+
outputs: z9.array(CompanionOutputSchema).min(1)
|
|
15128
15346
|
}).strict();
|
|
15129
|
-
var CompanionV1Schema =
|
|
15130
|
-
version:
|
|
15131
|
-
basedOn:
|
|
15132
|
-
sha256:
|
|
15133
|
-
editor:
|
|
15134
|
-
protocol:
|
|
15135
|
-
savedAt:
|
|
15136
|
-
project:
|
|
15347
|
+
var CompanionV1Schema = z9.object({
|
|
15348
|
+
version: z9.literal(1),
|
|
15349
|
+
basedOn: z9.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
15350
|
+
sha256: z9.string().regex(/^[0-9a-f]{64}$/),
|
|
15351
|
+
editor: z9.string().min(1),
|
|
15352
|
+
protocol: z9.number().int().positive(),
|
|
15353
|
+
savedAt: z9.string().datetime(),
|
|
15354
|
+
project: z9.string().min(1).nullable()
|
|
15137
15355
|
}).strict();
|
|
15138
|
-
var HandEditCompanionSchema =
|
|
15356
|
+
var HandEditCompanionSchema = z9.union([CompanionV2Schema, CompanionV1Schema]).transform(
|
|
15139
15357
|
(value) => value.version === 2 ? value : {
|
|
15140
15358
|
version: 2,
|
|
15141
15359
|
editor: value.editor,
|
|
@@ -15255,40 +15473,40 @@ function openInEditor(file, editor = process.env.PIXELKILN_EDITOR) {
|
|
|
15255
15473
|
}
|
|
15256
15474
|
|
|
15257
15475
|
// src/gallery/edit.ts
|
|
15258
|
-
var Base64 =
|
|
15259
|
-
var HandEditRequestSchema =
|
|
15260
|
-
|
|
15261
|
-
action:
|
|
15262
|
-
project:
|
|
15263
|
-
assetId:
|
|
15264
|
-
styleId:
|
|
15265
|
-
expectedSha256:
|
|
15476
|
+
var Base64 = z10.string().regex(/^[A-Za-z0-9+/]*={0,2}$/).max(Math.ceil(MAX_HAND_EDIT_BYTES / 3) * 4);
|
|
15477
|
+
var HandEditRequestSchema = z10.discriminatedUnion("action", [
|
|
15478
|
+
z10.object({
|
|
15479
|
+
action: z10.literal("start-edit"),
|
|
15480
|
+
project: z10.string().min(1).optional(),
|
|
15481
|
+
assetId: z10.string().min(1),
|
|
15482
|
+
styleId: z10.string().min(1),
|
|
15483
|
+
expectedSha256: z10.string().regex(/^[0-9a-f]{64}$/),
|
|
15266
15484
|
/** Also launch the author's editor on the file. */
|
|
15267
|
-
open:
|
|
15485
|
+
open: z10.boolean().optional()
|
|
15268
15486
|
}).strict(),
|
|
15269
|
-
|
|
15270
|
-
action:
|
|
15271
|
-
project:
|
|
15272
|
-
assetId:
|
|
15273
|
-
styleId:
|
|
15274
|
-
expectedSha256:
|
|
15487
|
+
z10.object({
|
|
15488
|
+
action: z10.literal("detach-edit"),
|
|
15489
|
+
project: z10.string().min(1).optional(),
|
|
15490
|
+
assetId: z10.string().min(1),
|
|
15491
|
+
styleId: z10.string().min(1),
|
|
15492
|
+
expectedSha256: z10.string().regex(/^[0-9a-f]{64}$/)
|
|
15275
15493
|
}).strict(),
|
|
15276
15494
|
/** From the in-browser editor: the page holds the bytes, the server validates and writes. */
|
|
15277
|
-
|
|
15278
|
-
action:
|
|
15279
|
-
project:
|
|
15280
|
-
assetId:
|
|
15281
|
-
styleId:
|
|
15282
|
-
expectedSha256:
|
|
15495
|
+
z10.object({
|
|
15496
|
+
action: z10.literal("save-edit"),
|
|
15497
|
+
project: z10.string().min(1).optional(),
|
|
15498
|
+
assetId: z10.string().min(1),
|
|
15499
|
+
styleId: z10.string().min(1),
|
|
15500
|
+
expectedSha256: z10.string().regex(/^[0-9a-f]{64}$/),
|
|
15283
15501
|
/** The flattened image; for a frame set, `frames` instead. */
|
|
15284
15502
|
png: Base64.min(1).optional(),
|
|
15285
15503
|
/** Every frame of a set, tagged with the role it was opened under (null for one added in the editor). */
|
|
15286
|
-
frames:
|
|
15504
|
+
frames: z10.array(z10.object({ role: z10.string().min(1).nullable(), png: Base64.min(1) }).strict()).min(1).max(256).optional(),
|
|
15287
15505
|
/** The editor's layered project file, kept beside the edit. */
|
|
15288
15506
|
pxo: Base64.optional(),
|
|
15289
15507
|
/** Editor identity from the bridge's ready message. */
|
|
15290
|
-
editor:
|
|
15291
|
-
protocol:
|
|
15508
|
+
editor: z10.string().min(1).max(200),
|
|
15509
|
+
protocol: z10.number().int().positive()
|
|
15292
15510
|
}).strict()
|
|
15293
15511
|
]);
|
|
15294
15512
|
function createGalleryEditHandler(opts) {
|
|
@@ -16622,27 +16840,27 @@ async function serveGallery(opts) {
|
|
|
16622
16840
|
|
|
16623
16841
|
// src/gallery/generate.ts
|
|
16624
16842
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
16625
|
-
import { z as
|
|
16626
|
-
var GenerateRequestSchema =
|
|
16627
|
-
project:
|
|
16628
|
-
keys:
|
|
16843
|
+
import { z as z11 } from "zod";
|
|
16844
|
+
var GenerateRequestSchema = z11.object({
|
|
16845
|
+
project: z11.string().min(1).optional(),
|
|
16846
|
+
keys: z11.array(z11.string().min(1)).min(1).max(500),
|
|
16629
16847
|
/**
|
|
16630
16848
|
* Regenerate work that is up to date, as `gen --force` does, and let the
|
|
16631
16849
|
* fetch replace a locally modified or untracked file. With `restore`, put
|
|
16632
16850
|
* the recorded bytes back over a modified file.
|
|
16633
16851
|
*/
|
|
16634
|
-
force:
|
|
16852
|
+
force: z11.boolean().optional(),
|
|
16635
16853
|
/** Advance in-flight, review, or selected work without submitting anything. */
|
|
16636
|
-
resume:
|
|
16854
|
+
resume: z11.boolean().optional(),
|
|
16637
16855
|
/** Re-download downloaded outputs and replace files whose object changed upstream. */
|
|
16638
|
-
refresh:
|
|
16856
|
+
refresh: z11.boolean().optional(),
|
|
16639
16857
|
/** Put recorded outputs back on disk from the cache or the provider, without generating. */
|
|
16640
|
-
restore:
|
|
16858
|
+
restore: z11.boolean().optional(),
|
|
16641
16859
|
/**
|
|
16642
16860
|
* Bring a replaced generation back: 1-based position in the record's
|
|
16643
16861
|
* history (newest first) or an output hash prefix. One key at a time.
|
|
16644
16862
|
*/
|
|
16645
|
-
revert:
|
|
16863
|
+
revert: z11.string().min(1).max(64).optional()
|
|
16646
16864
|
}).strict().refine((request) => [request.resume, request.refresh, request.restore, request.revert !== void 0].filter(Boolean).length <= 1, {
|
|
16647
16865
|
message: "resume, refresh, restore, and revert are exclusive"
|
|
16648
16866
|
}).refine((request) => request.revert === void 0 || request.keys.length === 1, { message: "revert takes one key" });
|