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.cjs
CHANGED
|
@@ -332,6 +332,7 @@ var RevisionModeSchema = import_zod.z.enum([
|
|
|
332
332
|
"correct-pixelart",
|
|
333
333
|
"animate",
|
|
334
334
|
"animate-pixminimax",
|
|
335
|
+
"animate-skeleton",
|
|
335
336
|
"interpolate",
|
|
336
337
|
"edit-animation"
|
|
337
338
|
]);
|
|
@@ -650,6 +651,30 @@ var RevisionSchema = import_zod.z.object({
|
|
|
650
651
|
direction: CharacterDirectionSchema.optional(),
|
|
651
652
|
/** `animate`/`animate-pixminimax` only: let PixelLab expand the action into a fuller motion description first. */
|
|
652
653
|
enhancePrompt: import_zod.z.boolean().optional(),
|
|
654
|
+
/**
|
|
655
|
+
* `animate-skeleton` only: manifest-relative path to a committed
|
|
656
|
+
* `SkeletonSet` JSON file (see `src/skeleton.ts`) — the pose the parent
|
|
657
|
+
* image is already in, plus 3-15 per-frame poses for the motion.
|
|
658
|
+
* Authored via `pixelkiln estimate-skeleton`, then hand-tweaked; never
|
|
659
|
+
* inline in the manifest, the same reasoning `mask`/`lastFrame` are
|
|
660
|
+
* committed files rather than inline pixel data.
|
|
661
|
+
*/
|
|
662
|
+
keypointsFile: import_zod.z.string().min(1).optional(),
|
|
663
|
+
/**
|
|
664
|
+
* `animate-skeleton` only: the body a joint's missing `depth` is taken
|
|
665
|
+
* from. PixelLab's default is `mannequin`; free string like `character`'s
|
|
666
|
+
* own `template` field, validated at the provider layer against the
|
|
667
|
+
* same `mannequin`/`bear`/`cat`/`dog`/`horse`/`lion` vocabulary.
|
|
668
|
+
*/
|
|
669
|
+
skeletonTemplate: import_zod.z.string().min(1).optional(),
|
|
670
|
+
/**
|
|
671
|
+
* `animate-skeleton` only: what the character *looks like*, a noun
|
|
672
|
+
* phrase (colours, clothing, held items) — distinct from the asset's
|
|
673
|
+
* own `prompt`, which this mode sends as the motion's short label
|
|
674
|
+
* (PixelLab's `action`), the same `prompt`-as-motion convention
|
|
675
|
+
* `animate`/`animate-pixminimax` already use.
|
|
676
|
+
*/
|
|
677
|
+
description: import_zod.z.string().min(1).optional(),
|
|
653
678
|
/**
|
|
654
679
|
* `image-to-image`/`inpaint` only: which provider engine draws the
|
|
655
680
|
* edit. `pro-flash` selects PixelLab's Pro Flash edit and inpaint tier
|
|
@@ -740,18 +765,41 @@ var RevisionSchema = import_zod.z.object({
|
|
|
740
765
|
path: ["fps"]
|
|
741
766
|
});
|
|
742
767
|
}
|
|
743
|
-
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax") {
|
|
768
|
+
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax" && revision.mode !== "animate-skeleton") {
|
|
744
769
|
context.addIssue({
|
|
745
770
|
code: import_zod.z.ZodIssueCode.custom,
|
|
746
|
-
message: "direction applies to animate-pixminimax revisions only",
|
|
771
|
+
message: "direction applies to animate-pixminimax/animate-skeleton revisions only",
|
|
772
|
+
path: ["direction"]
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
if (revision.mode === "animate-skeleton" && revision.direction === void 0) {
|
|
776
|
+
context.addIssue({
|
|
777
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
778
|
+
message: "animate-skeleton revisions require a direction",
|
|
747
779
|
path: ["direction"]
|
|
748
780
|
});
|
|
749
781
|
}
|
|
750
782
|
if (revision.frames !== void 0 && revision.frames % 2 !== 0) {
|
|
751
783
|
context.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: "frames must be even", path: ["frames"] });
|
|
752
784
|
}
|
|
785
|
+
if (revision.mode === "animate-skeleton" && !revision.keypointsFile) {
|
|
786
|
+
context.addIssue({
|
|
787
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
788
|
+
message: "animate-skeleton revisions require keypointsFile",
|
|
789
|
+
path: ["keypointsFile"]
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
for (const field of ["keypointsFile", "skeletonTemplate", "description"]) {
|
|
793
|
+
if (revision[field] !== void 0 && revision.mode !== "animate-skeleton") {
|
|
794
|
+
context.addIssue({
|
|
795
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
796
|
+
message: `${field} applies to animate-skeleton revisions only`,
|
|
797
|
+
path: [field]
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
}
|
|
753
801
|
});
|
|
754
|
-
var FRAME_SET_REVISION_MODES = ["animate", "animate-pixminimax", "interpolate", "edit-animation"];
|
|
802
|
+
var FRAME_SET_REVISION_MODES = ["animate", "animate-pixminimax", "animate-skeleton", "interpolate", "edit-animation"];
|
|
755
803
|
var MEMBER_SET_REVISION_MODES = ["reduce-colors", "correct-pixelart", "edit-animation"];
|
|
756
804
|
var StyleObjectSchema = import_zod.z.object({
|
|
757
805
|
/** Generation backend for this style. Omit to inherit the manifest default. */
|
|
@@ -1383,11 +1431,16 @@ var LockEntrySchema = import_zod.z.object({
|
|
|
1383
1431
|
paletteImageSha256: import_zod.z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1384
1432
|
dithering: RevisionDitheringSchema.optional(),
|
|
1385
1433
|
ditheringStrength: import_zod.z.number().min(0).max(10).optional(),
|
|
1386
|
-
|
|
1434
|
+
// 4-40 for animate/animate-pixminimax; animate-skeleton's own 3-15
|
|
1435
|
+
// range extends the floor down to 3, hence min(3) here rather than 4.
|
|
1436
|
+
frames: import_zod.z.number().int().min(3).max(40).optional(),
|
|
1387
1437
|
fps: import_zod.z.number().int().min(1).max(60).optional(),
|
|
1388
1438
|
lastFrameSha256: import_zod.z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1389
1439
|
direction: CharacterDirectionSchema.optional(),
|
|
1390
1440
|
enhancePrompt: import_zod.z.boolean().optional(),
|
|
1441
|
+
keypointsSha256: import_zod.z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1442
|
+
skeletonTemplate: import_zod.z.string().min(1).optional(),
|
|
1443
|
+
description: import_zod.z.string().min(1).optional(),
|
|
1391
1444
|
engine: import_zod.z.enum(["pro-flash"]).optional()
|
|
1392
1445
|
}).strict().nullable().default(null),
|
|
1393
1446
|
/** For a mirror: the asset it flips and a hash over that asset's output hashes when this was made. */
|
|
@@ -1574,7 +1627,7 @@ function exitCodeFor(err) {
|
|
|
1574
1627
|
}
|
|
1575
1628
|
|
|
1576
1629
|
// src/client.ts
|
|
1577
|
-
var
|
|
1630
|
+
var import_zod3 = require("zod");
|
|
1578
1631
|
|
|
1579
1632
|
// src/http.ts
|
|
1580
1633
|
var MAX_RETRIES = 4;
|
|
@@ -1624,262 +1677,289 @@ function fetchWithRetry(request, opts = {}) {
|
|
|
1624
1677
|
};
|
|
1625
1678
|
}
|
|
1626
1679
|
|
|
1680
|
+
// src/skeleton.ts
|
|
1681
|
+
var import_zod2 = require("zod");
|
|
1682
|
+
var SkeletonKeypointSchema = import_zod2.z.object({
|
|
1683
|
+
label: import_zod2.z.string().min(1),
|
|
1684
|
+
x: import_zod2.z.number().min(0).max(1),
|
|
1685
|
+
y: import_zod2.z.number().min(0).max(1),
|
|
1686
|
+
z_index: import_zod2.z.number(),
|
|
1687
|
+
depth: import_zod2.z.number().optional()
|
|
1688
|
+
}).strict();
|
|
1689
|
+
var SkeletonFrameSchema = import_zod2.z.array(SkeletonKeypointSchema).length(18);
|
|
1690
|
+
var SkeletonSetSchema = import_zod2.z.object({
|
|
1691
|
+
firstFrameKeypoints: SkeletonFrameSchema,
|
|
1692
|
+
frames: import_zod2.z.array(SkeletonFrameSchema).min(3).max(15)
|
|
1693
|
+
}).strict();
|
|
1694
|
+
function parseSkeletonSet(json, file) {
|
|
1695
|
+
const result = SkeletonSetSchema.safeParse(json);
|
|
1696
|
+
if (!result.success) {
|
|
1697
|
+
const issues = result.error.issues.slice(0, 4).map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join("; ");
|
|
1698
|
+
throw new Error(`revision keypoints file ${file} does not match the expected shape: ${issues}`);
|
|
1699
|
+
}
|
|
1700
|
+
return result.data;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1627
1703
|
// src/client.ts
|
|
1628
1704
|
var BASE = process.env.PIXELLAB_API_BASE ?? "https://api.pixellab.ai/v2";
|
|
1629
1705
|
var MAX_DOWNLOAD_BYTES = 64 * 1024 * 1024;
|
|
1630
|
-
var BalanceResponseSchema =
|
|
1631
|
-
credits:
|
|
1632
|
-
subscription:
|
|
1633
|
-
generations:
|
|
1634
|
-
total:
|
|
1635
|
-
plan:
|
|
1706
|
+
var BalanceResponseSchema = import_zod3.z.object({
|
|
1707
|
+
credits: import_zod3.z.object({ usd: import_zod3.z.number() }).passthrough(),
|
|
1708
|
+
subscription: import_zod3.z.object({
|
|
1709
|
+
generations: import_zod3.z.number(),
|
|
1710
|
+
total: import_zod3.z.number(),
|
|
1711
|
+
plan: import_zod3.z.string().nullable().optional()
|
|
1636
1712
|
}).passthrough()
|
|
1637
1713
|
}).passthrough();
|
|
1638
|
-
var ObjectSubmitSchema =
|
|
1639
|
-
background_job_id:
|
|
1640
|
-
object_id:
|
|
1641
|
-
status:
|
|
1642
|
-
n_frames:
|
|
1714
|
+
var ObjectSubmitSchema = import_zod3.z.object({
|
|
1715
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1716
|
+
object_id: import_zod3.z.string().min(1),
|
|
1717
|
+
status: import_zod3.z.string().default("queued"),
|
|
1718
|
+
n_frames: import_zod3.z.number().int().min(0)
|
|
1643
1719
|
}).passthrough();
|
|
1644
|
-
var MapSubmitSchema =
|
|
1645
|
-
background_job_id:
|
|
1646
|
-
object_id:
|
|
1647
|
-
status:
|
|
1720
|
+
var MapSubmitSchema = import_zod3.z.object({
|
|
1721
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1722
|
+
object_id: import_zod3.z.string().min(1),
|
|
1723
|
+
status: import_zod3.z.string().default("processing")
|
|
1648
1724
|
}).passthrough();
|
|
1649
|
-
var UsageSchema =
|
|
1650
|
-
type:
|
|
1651
|
-
usd:
|
|
1652
|
-
generations:
|
|
1725
|
+
var UsageSchema = import_zod3.z.object({
|
|
1726
|
+
type: import_zod3.z.string().optional(),
|
|
1727
|
+
usd: import_zod3.z.number().nullable().optional(),
|
|
1728
|
+
generations: import_zod3.z.number().nullable().optional()
|
|
1653
1729
|
}).passthrough().nullable().optional();
|
|
1654
|
-
var TilesSubmitSchema =
|
|
1655
|
-
tile_id:
|
|
1656
|
-
background_job_id:
|
|
1657
|
-
status:
|
|
1730
|
+
var TilesSubmitSchema = import_zod3.z.object({
|
|
1731
|
+
tile_id: import_zod3.z.string().min(1),
|
|
1732
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1733
|
+
status: import_zod3.z.literal("processing").default("processing")
|
|
1658
1734
|
}).passthrough();
|
|
1659
|
-
var TilesProSchema =
|
|
1660
|
-
storage_urls:
|
|
1661
|
-
kind:
|
|
1662
|
-
tile_rules:
|
|
1735
|
+
var TilesProSchema = import_zod3.z.object({
|
|
1736
|
+
storage_urls: import_zod3.z.record(import_zod3.z.string()),
|
|
1737
|
+
kind: import_zod3.z.string().nullable().default(null),
|
|
1738
|
+
tile_rules: import_zod3.z.record(import_zod3.z.unknown()).nullable().optional()
|
|
1663
1739
|
}).passthrough();
|
|
1664
|
-
var TilesetSubmitSchema =
|
|
1665
|
-
tileset_id:
|
|
1666
|
-
background_job_id:
|
|
1667
|
-
status:
|
|
1740
|
+
var TilesetSubmitSchema = import_zod3.z.object({
|
|
1741
|
+
tileset_id: import_zod3.z.string().min(1),
|
|
1742
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1743
|
+
status: import_zod3.z.literal("processing").default("processing")
|
|
1668
1744
|
}).passthrough();
|
|
1669
|
-
var TilesetTileSchema =
|
|
1670
|
-
id:
|
|
1671
|
-
name:
|
|
1672
|
-
image:
|
|
1673
|
-
corners:
|
|
1674
|
-
pattern_4x4:
|
|
1675
|
-
row_0:
|
|
1676
|
-
row_1:
|
|
1677
|
-
row_2:
|
|
1678
|
-
row_3:
|
|
1745
|
+
var TilesetTileSchema = import_zod3.z.object({
|
|
1746
|
+
id: import_zod3.z.string().min(1),
|
|
1747
|
+
name: import_zod3.z.string(),
|
|
1748
|
+
image: import_zod3.z.object({ base64: import_zod3.z.string().min(1), format: import_zod3.z.string().default("png") }).passthrough(),
|
|
1749
|
+
corners: import_zod3.z.object({ NW: import_zod3.z.string(), NE: import_zod3.z.string(), SW: import_zod3.z.string(), SE: import_zod3.z.string() }).passthrough(),
|
|
1750
|
+
pattern_4x4: import_zod3.z.object({
|
|
1751
|
+
row_0: import_zod3.z.array(import_zod3.z.number()),
|
|
1752
|
+
row_1: import_zod3.z.array(import_zod3.z.number()),
|
|
1753
|
+
row_2: import_zod3.z.array(import_zod3.z.number()),
|
|
1754
|
+
row_3: import_zod3.z.array(import_zod3.z.number())
|
|
1679
1755
|
}).passthrough()
|
|
1680
1756
|
}).passthrough();
|
|
1681
|
-
var TilesetGetSchema =
|
|
1682
|
-
tileset:
|
|
1683
|
-
total_tiles:
|
|
1684
|
-
tile_size:
|
|
1685
|
-
terrain_types:
|
|
1686
|
-
tiles:
|
|
1757
|
+
var TilesetGetSchema = import_zod3.z.object({
|
|
1758
|
+
tileset: import_zod3.z.object({
|
|
1759
|
+
total_tiles: import_zod3.z.number().int().min(1),
|
|
1760
|
+
tile_size: import_zod3.z.object({ width: import_zod3.z.number().int().positive(), height: import_zod3.z.number().int().positive() }).passthrough(),
|
|
1761
|
+
terrain_types: import_zod3.z.array(import_zod3.z.string()),
|
|
1762
|
+
tiles: import_zod3.z.array(TilesetTileSchema).min(1)
|
|
1687
1763
|
}).passthrough(),
|
|
1688
1764
|
usage: UsageSchema
|
|
1689
1765
|
}).passthrough();
|
|
1690
|
-
var IsometricTileSubmitSchema =
|
|
1691
|
-
tile_id:
|
|
1692
|
-
background_job_id:
|
|
1693
|
-
status:
|
|
1766
|
+
var IsometricTileSubmitSchema = import_zod3.z.object({
|
|
1767
|
+
tile_id: import_zod3.z.string().min(1),
|
|
1768
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1769
|
+
status: import_zod3.z.literal("processing").default("processing")
|
|
1694
1770
|
}).passthrough();
|
|
1695
|
-
var IsometricTileGetSchema =
|
|
1696
|
-
image:
|
|
1771
|
+
var IsometricTileGetSchema = import_zod3.z.object({
|
|
1772
|
+
image: import_zod3.z.object({ base64: import_zod3.z.string().min(1), format: import_zod3.z.string().default("png") }).passthrough(),
|
|
1697
1773
|
usage: UsageSchema
|
|
1698
1774
|
}).passthrough();
|
|
1699
|
-
var UiAssetSubmitSchema =
|
|
1700
|
-
ui_asset_id:
|
|
1701
|
-
background_job_id:
|
|
1702
|
-
status:
|
|
1775
|
+
var UiAssetSubmitSchema = import_zod3.z.object({
|
|
1776
|
+
ui_asset_id: import_zod3.z.string().min(1),
|
|
1777
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1778
|
+
status: import_zod3.z.string().default("processing"),
|
|
1703
1779
|
usage: UsageSchema
|
|
1704
1780
|
}).passthrough();
|
|
1705
|
-
var UiAssetGetSchema =
|
|
1706
|
-
id:
|
|
1707
|
-
status:
|
|
1708
|
-
image_url:
|
|
1709
|
-
progress_percent:
|
|
1710
|
-
eta_seconds:
|
|
1781
|
+
var UiAssetGetSchema = import_zod3.z.object({
|
|
1782
|
+
id: import_zod3.z.string().min(1),
|
|
1783
|
+
status: import_zod3.z.string().nullable().default(null),
|
|
1784
|
+
image_url: import_zod3.z.string().nullable().optional(),
|
|
1785
|
+
progress_percent: import_zod3.z.number().nullable().optional(),
|
|
1786
|
+
eta_seconds: import_zod3.z.number().nullable().optional()
|
|
1711
1787
|
}).passthrough();
|
|
1712
|
-
var RevisionJobSubmitSchema =
|
|
1713
|
-
background_job_id:
|
|
1714
|
-
status:
|
|
1788
|
+
var RevisionJobSubmitSchema = import_zod3.z.object({
|
|
1789
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1790
|
+
status: import_zod3.z.string().default("processing")
|
|
1715
1791
|
}).passthrough();
|
|
1716
|
-
var ObjectAnimationGroupSchema =
|
|
1717
|
-
animation_group_id:
|
|
1718
|
-
display_name:
|
|
1719
|
-
description:
|
|
1720
|
-
frame_count:
|
|
1721
|
-
directions:
|
|
1722
|
-
|
|
1723
|
-
direction:
|
|
1724
|
-
storage_urls:
|
|
1725
|
-
created_at:
|
|
1792
|
+
var ObjectAnimationGroupSchema = import_zod3.z.object({
|
|
1793
|
+
animation_group_id: import_zod3.z.string().min(1),
|
|
1794
|
+
display_name: import_zod3.z.string().nullable().default(null),
|
|
1795
|
+
description: import_zod3.z.string().default(""),
|
|
1796
|
+
frame_count: import_zod3.z.number().int().default(0),
|
|
1797
|
+
directions: import_zod3.z.array(
|
|
1798
|
+
import_zod3.z.object({
|
|
1799
|
+
direction: import_zod3.z.string(),
|
|
1800
|
+
storage_urls: import_zod3.z.record(import_zod3.z.unknown()).default({}),
|
|
1801
|
+
created_at: import_zod3.z.string()
|
|
1726
1802
|
}).passthrough()
|
|
1727
1803
|
).default([])
|
|
1728
1804
|
}).passthrough();
|
|
1729
|
-
var PixelLabObjectSchema =
|
|
1730
|
-
id:
|
|
1731
|
-
name:
|
|
1732
|
-
state_name:
|
|
1733
|
-
prompt:
|
|
1734
|
-
size:
|
|
1735
|
-
directions:
|
|
1736
|
-
created_at:
|
|
1737
|
-
view:
|
|
1738
|
-
preview_url:
|
|
1739
|
-
rotation_urls:
|
|
1740
|
-
frame_urls:
|
|
1741
|
-
tags:
|
|
1742
|
-
status:
|
|
1743
|
-
progress_percent:
|
|
1744
|
-
eta_seconds:
|
|
1745
|
-
group_id:
|
|
1746
|
-
animations:
|
|
1805
|
+
var PixelLabObjectSchema = import_zod3.z.object({
|
|
1806
|
+
id: import_zod3.z.string().min(1),
|
|
1807
|
+
name: import_zod3.z.string().nullable().default(null),
|
|
1808
|
+
state_name: import_zod3.z.string().nullable().optional(),
|
|
1809
|
+
prompt: import_zod3.z.string().default(""),
|
|
1810
|
+
size: import_zod3.z.object({ width: import_zod3.z.number().int().positive(), height: import_zod3.z.number().int().positive() }),
|
|
1811
|
+
directions: import_zod3.z.number().default(0),
|
|
1812
|
+
created_at: import_zod3.z.string(),
|
|
1813
|
+
view: import_zod3.z.string().nullable().default(null),
|
|
1814
|
+
preview_url: import_zod3.z.string().nullable().optional(),
|
|
1815
|
+
rotation_urls: import_zod3.z.record(import_zod3.z.string().nullable()).nullable().optional(),
|
|
1816
|
+
frame_urls: import_zod3.z.array(import_zod3.z.string()).nullable().optional(),
|
|
1817
|
+
tags: import_zod3.z.array(import_zod3.z.string()).default([]),
|
|
1818
|
+
status: import_zod3.z.string().nullable().default(null),
|
|
1819
|
+
progress_percent: import_zod3.z.number().nullable().optional(),
|
|
1820
|
+
eta_seconds: import_zod3.z.number().nullable().optional(),
|
|
1821
|
+
group_id: import_zod3.z.string().nullable().optional(),
|
|
1822
|
+
animations: import_zod3.z.array(ObjectAnimationGroupSchema).default([])
|
|
1823
|
+
}).passthrough();
|
|
1824
|
+
var MapObjectSchema = import_zod3.z.object({
|
|
1825
|
+
object_id: import_zod3.z.string().min(1),
|
|
1826
|
+
status: import_zod3.z.string(),
|
|
1827
|
+
description: import_zod3.z.string().nullable().default(null),
|
|
1828
|
+
width: import_zod3.z.number().nullable().default(null),
|
|
1829
|
+
height: import_zod3.z.number().nullable().default(null),
|
|
1830
|
+
download_url: import_zod3.z.string().nullable().default(null)
|
|
1747
1831
|
}).passthrough();
|
|
1748
|
-
var
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1832
|
+
var ObjectListSchema = import_zod3.z.object({ objects: import_zod3.z.array(PixelLabObjectSchema), total: import_zod3.z.number().int().min(0) }).passthrough();
|
|
1833
|
+
var PixfluxResponseSchema = import_zod3.z.object({ image: import_zod3.z.object({ base64: import_zod3.z.string().min(1) }).passthrough(), usage: import_zod3.z.unknown().optional() }).passthrough();
|
|
1834
|
+
var ReduceColorsResponseSchema = import_zod3.z.object({
|
|
1835
|
+
images: import_zod3.z.array(import_zod3.z.object({ base64: import_zod3.z.string().min(1) }).passthrough()).min(1),
|
|
1836
|
+
palette: import_zod3.z.object({ base64: import_zod3.z.string().min(1) }).passthrough(),
|
|
1837
|
+
n_colors: import_zod3.z.number().int(),
|
|
1838
|
+
usage: import_zod3.z.unknown().optional()
|
|
1755
1839
|
}).passthrough();
|
|
1756
|
-
var
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
images: import_zod2.z.array(import_zod2.z.object({ base64: import_zod2.z.string().min(1) }).passthrough()).min(1),
|
|
1760
|
-
palette: import_zod2.z.object({ base64: import_zod2.z.string().min(1) }).passthrough(),
|
|
1761
|
-
n_colors: import_zod2.z.number().int(),
|
|
1762
|
-
usage: import_zod2.z.unknown().optional()
|
|
1840
|
+
var CorrectPixelartResponseSchema = import_zod3.z.object({
|
|
1841
|
+
images: import_zod3.z.array(import_zod3.z.object({ base64: import_zod3.z.string().min(1) }).passthrough()).min(1),
|
|
1842
|
+
usage: import_zod3.z.unknown().optional()
|
|
1763
1843
|
}).passthrough();
|
|
1764
|
-
var
|
|
1765
|
-
|
|
1766
|
-
|
|
1844
|
+
var ProFlashImageSubmitSchema = import_zod3.z.object({
|
|
1845
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1846
|
+
image_id: import_zod3.z.string().min(1),
|
|
1847
|
+
source_image_id: import_zod3.z.string().min(1),
|
|
1848
|
+
status: import_zod3.z.string().default("processing"),
|
|
1849
|
+
estimated_generations: import_zod3.z.number().nullable().optional(),
|
|
1850
|
+
usage: import_zod3.z.unknown().optional()
|
|
1767
1851
|
}).passthrough();
|
|
1768
|
-
var
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
usage: import_zod2.z.unknown().optional()
|
|
1852
|
+
var UnzoomResponseSchema = import_zod3.z.object({
|
|
1853
|
+
image: import_zod3.z.object({ base64: import_zod3.z.string().min(1) }).passthrough(),
|
|
1854
|
+
original_size: import_zod3.z.object({ width: import_zod3.z.number().int(), height: import_zod3.z.number().int() }).passthrough(),
|
|
1855
|
+
unzoomed_size: import_zod3.z.object({ width: import_zod3.z.number().int(), height: import_zod3.z.number().int() }).passthrough(),
|
|
1856
|
+
zoom_factor_detected: import_zod3.z.number(),
|
|
1857
|
+
usage: import_zod3.z.unknown().optional()
|
|
1775
1858
|
}).passthrough();
|
|
1776
|
-
var
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1859
|
+
var FontJobSchema = import_zod3.z.object({
|
|
1860
|
+
job_id: import_zod3.z.string().min(1),
|
|
1861
|
+
status: import_zod3.z.string(),
|
|
1862
|
+
glyph_px: import_zod3.z.number().int().nullable().optional(),
|
|
1863
|
+
download_atlas_url: import_zod3.z.string().nullable().optional(),
|
|
1864
|
+
download_ttf_url: import_zod3.z.string().nullable().optional(),
|
|
1865
|
+
usage: import_zod3.z.unknown().optional()
|
|
1782
1866
|
}).passthrough();
|
|
1783
|
-
var
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
download_atlas_url: import_zod2.z.string().nullable().optional(),
|
|
1788
|
-
download_ttf_url: import_zod2.z.string().nullable().optional(),
|
|
1789
|
-
usage: import_zod2.z.unknown().optional()
|
|
1867
|
+
var SelectFramesSchema = import_zod3.z.object({ created_object_ids: import_zod3.z.array(import_zod3.z.string()) }).passthrough();
|
|
1868
|
+
var EstimateSkeletonResponseSchema = import_zod3.z.object({
|
|
1869
|
+
keypoints: import_zod3.z.array(SkeletonKeypointSchema).length(18),
|
|
1870
|
+
usage: import_zod3.z.unknown().optional()
|
|
1790
1871
|
}).passthrough();
|
|
1791
|
-
var
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
status: import_zod2.z.string().default("processing"),
|
|
1872
|
+
var CharacterSubmitSchema = import_zod3.z.object({
|
|
1873
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1874
|
+
character_id: import_zod3.z.string().min(1),
|
|
1875
|
+
status: import_zod3.z.string().default("processing"),
|
|
1796
1876
|
usage: UsageSchema
|
|
1797
1877
|
}).passthrough();
|
|
1798
|
-
var AnimateSubmitSchema =
|
|
1799
|
-
background_job_ids:
|
|
1800
|
-
directions:
|
|
1801
|
-
status:
|
|
1878
|
+
var AnimateSubmitSchema = import_zod3.z.object({
|
|
1879
|
+
background_job_ids: import_zod3.z.array(import_zod3.z.string()),
|
|
1880
|
+
directions: import_zod3.z.array(import_zod3.z.string()),
|
|
1881
|
+
status: import_zod3.z.string().default("processing"),
|
|
1802
1882
|
usage: UsageSchema
|
|
1803
1883
|
}).passthrough();
|
|
1804
|
-
var ObjectProSubmitSchema =
|
|
1805
|
-
object_id:
|
|
1806
|
-
background_job_id:
|
|
1807
|
-
status:
|
|
1884
|
+
var ObjectProSubmitSchema = import_zod3.z.object({
|
|
1885
|
+
object_id: import_zod3.z.string().min(1),
|
|
1886
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1887
|
+
status: import_zod3.z.string().default("processing"),
|
|
1808
1888
|
usage: UsageSchema
|
|
1809
1889
|
}).passthrough();
|
|
1810
|
-
var DirectionSubmissionSchema =
|
|
1811
|
-
direction:
|
|
1812
|
-
status:
|
|
1813
|
-
background_job_id:
|
|
1814
|
-
animation_id:
|
|
1890
|
+
var DirectionSubmissionSchema = import_zod3.z.object({
|
|
1891
|
+
direction: import_zod3.z.string(),
|
|
1892
|
+
status: import_zod3.z.string(),
|
|
1893
|
+
background_job_id: import_zod3.z.string().nullable().default(null),
|
|
1894
|
+
animation_id: import_zod3.z.string().nullable().default(null)
|
|
1815
1895
|
}).passthrough();
|
|
1816
|
-
var AnimateObjectSubmitSchema =
|
|
1817
|
-
animation_group_id:
|
|
1818
|
-
object_id:
|
|
1819
|
-
mode:
|
|
1820
|
-
frame_count:
|
|
1821
|
-
display_name:
|
|
1822
|
-
description:
|
|
1823
|
-
submissions:
|
|
1896
|
+
var AnimateObjectSubmitSchema = import_zod3.z.object({
|
|
1897
|
+
animation_group_id: import_zod3.z.string().min(1),
|
|
1898
|
+
object_id: import_zod3.z.string().min(1),
|
|
1899
|
+
mode: import_zod3.z.string(),
|
|
1900
|
+
frame_count: import_zod3.z.number().int(),
|
|
1901
|
+
display_name: import_zod3.z.string().nullable().default(null),
|
|
1902
|
+
description: import_zod3.z.string().default(""),
|
|
1903
|
+
submissions: import_zod3.z.array(DirectionSubmissionSchema),
|
|
1824
1904
|
usage: UsageSchema
|
|
1825
1905
|
}).passthrough();
|
|
1826
|
-
var PortraitSubmitSchema =
|
|
1827
|
-
background_job_id:
|
|
1828
|
-
status:
|
|
1906
|
+
var PortraitSubmitSchema = import_zod3.z.object({
|
|
1907
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1908
|
+
status: import_zod3.z.string().default("processing"),
|
|
1829
1909
|
usage: UsageSchema
|
|
1830
1910
|
}).passthrough();
|
|
1831
|
-
var PortraitJobSchema =
|
|
1832
|
-
status:
|
|
1833
|
-
download_url:
|
|
1834
|
-
width:
|
|
1835
|
-
height:
|
|
1911
|
+
var PortraitJobSchema = import_zod3.z.object({
|
|
1912
|
+
status: import_zod3.z.string(),
|
|
1913
|
+
download_url: import_zod3.z.string().nullable().optional(),
|
|
1914
|
+
width: import_zod3.z.number().int().nullable().optional(),
|
|
1915
|
+
height: import_zod3.z.number().int().nullable().optional()
|
|
1836
1916
|
}).passthrough();
|
|
1837
|
-
var SetPortraitSchema =
|
|
1838
|
-
character_id:
|
|
1839
|
-
size:
|
|
1840
|
-
url:
|
|
1917
|
+
var SetPortraitSchema = import_zod3.z.object({
|
|
1918
|
+
character_id: import_zod3.z.string().min(1),
|
|
1919
|
+
size: import_zod3.z.number().int().positive(),
|
|
1920
|
+
url: import_zod3.z.string().min(1),
|
|
1841
1921
|
usage: UsageSchema
|
|
1842
1922
|
}).passthrough();
|
|
1843
|
-
var TransferOutfitSubmitSchema =
|
|
1844
|
-
background_job_id:
|
|
1845
|
-
status:
|
|
1923
|
+
var TransferOutfitSubmitSchema = import_zod3.z.object({
|
|
1924
|
+
background_job_id: import_zod3.z.string().min(1),
|
|
1925
|
+
status: import_zod3.z.string().default("processing"),
|
|
1846
1926
|
usage: UsageSchema
|
|
1847
1927
|
}).passthrough();
|
|
1848
|
-
var CharacterAnimationDirectionSchema =
|
|
1849
|
-
direction:
|
|
1850
|
-
frame_count:
|
|
1851
|
-
frames:
|
|
1928
|
+
var CharacterAnimationDirectionSchema = import_zod3.z.object({
|
|
1929
|
+
direction: import_zod3.z.string(),
|
|
1930
|
+
frame_count: import_zod3.z.number().int().min(0),
|
|
1931
|
+
frames: import_zod3.z.array(import_zod3.z.string())
|
|
1852
1932
|
}).passthrough();
|
|
1853
|
-
var CharacterAnimationSchema2 =
|
|
1854
|
-
animation_type:
|
|
1855
|
-
display_name:
|
|
1856
|
-
animation_group_id:
|
|
1857
|
-
directions:
|
|
1933
|
+
var CharacterAnimationSchema2 = import_zod3.z.object({
|
|
1934
|
+
animation_type: import_zod3.z.string(),
|
|
1935
|
+
display_name: import_zod3.z.string().nullable().optional(),
|
|
1936
|
+
animation_group_id: import_zod3.z.string().nullable().optional(),
|
|
1937
|
+
directions: import_zod3.z.array(CharacterAnimationDirectionSchema)
|
|
1858
1938
|
}).passthrough();
|
|
1859
|
-
var CharacterSchema =
|
|
1860
|
-
id:
|
|
1861
|
-
name:
|
|
1862
|
-
state_name:
|
|
1863
|
-
prompt:
|
|
1864
|
-
size:
|
|
1865
|
-
directions:
|
|
1866
|
-
created_at:
|
|
1867
|
-
updated_at:
|
|
1868
|
-
animation_count:
|
|
1869
|
-
template_id:
|
|
1870
|
-
view:
|
|
1871
|
-
status:
|
|
1872
|
-
rotation_urls:
|
|
1873
|
-
tags:
|
|
1874
|
-
group_id:
|
|
1875
|
-
animations:
|
|
1876
|
-
preview_url:
|
|
1939
|
+
var CharacterSchema = import_zod3.z.object({
|
|
1940
|
+
id: import_zod3.z.string().min(1),
|
|
1941
|
+
name: import_zod3.z.string().default(""),
|
|
1942
|
+
state_name: import_zod3.z.string().nullable().optional(),
|
|
1943
|
+
prompt: import_zod3.z.string().default(""),
|
|
1944
|
+
size: import_zod3.z.object({ width: import_zod3.z.number().int().positive(), height: import_zod3.z.number().int().positive() }),
|
|
1945
|
+
directions: import_zod3.z.number().int(),
|
|
1946
|
+
created_at: import_zod3.z.string(),
|
|
1947
|
+
updated_at: import_zod3.z.string().nullable().optional(),
|
|
1948
|
+
animation_count: import_zod3.z.number().int().default(0),
|
|
1949
|
+
template_id: import_zod3.z.string().default("mannequin"),
|
|
1950
|
+
view: import_zod3.z.string().nullable().optional(),
|
|
1951
|
+
status: import_zod3.z.string().default("completed"),
|
|
1952
|
+
rotation_urls: import_zod3.z.record(import_zod3.z.string().nullable()).nullable().optional(),
|
|
1953
|
+
tags: import_zod3.z.array(import_zod3.z.string()).default([]),
|
|
1954
|
+
group_id: import_zod3.z.string().nullable().optional(),
|
|
1955
|
+
animations: import_zod3.z.array(CharacterAnimationSchema2).default([]),
|
|
1956
|
+
preview_url: import_zod3.z.string().nullable().optional()
|
|
1877
1957
|
}).passthrough();
|
|
1878
|
-
var CharacterListSchema =
|
|
1879
|
-
var BackgroundJobSchema =
|
|
1880
|
-
id:
|
|
1881
|
-
status:
|
|
1882
|
-
last_response:
|
|
1958
|
+
var CharacterListSchema = import_zod3.z.object({ characters: import_zod3.z.array(CharacterSchema), total: import_zod3.z.number().int().min(0) }).passthrough();
|
|
1959
|
+
var BackgroundJobSchema = import_zod3.z.object({
|
|
1960
|
+
id: import_zod3.z.string(),
|
|
1961
|
+
status: import_zod3.z.string(),
|
|
1962
|
+
last_response: import_zod3.z.record(import_zod3.z.unknown()).nullable().optional(),
|
|
1883
1963
|
/**
|
|
1884
1964
|
* The billed amount, confirmed live for a `map` object and a standard
|
|
1885
1965
|
* character base (docs/ENDPOINTS.md, "Limits and billing"); duplicated at
|
|
@@ -1887,7 +1967,7 @@ var BackgroundJobSchema = import_zod2.z.object({
|
|
|
1887
1967
|
*/
|
|
1888
1968
|
usage: UsageSchema
|
|
1889
1969
|
}).passthrough();
|
|
1890
|
-
var DeleteAnimationsSchema =
|
|
1970
|
+
var DeleteAnimationsSchema = import_zod3.z.object({ success: import_zod3.z.boolean(), deleted_count: import_zod3.z.number().int().default(0), error: import_zod3.z.string().nullable().optional() }).passthrough();
|
|
1891
1971
|
function validateResponse(schema, raw, operation) {
|
|
1892
1972
|
const parsed = schema.safeParse(raw);
|
|
1893
1973
|
if (parsed.success) return parsed.data;
|
|
@@ -2918,6 +2998,61 @@ var PixelLabClient = class {
|
|
|
2918
2998
|
"animate-pixminimax"
|
|
2919
2999
|
);
|
|
2920
3000
|
}
|
|
3001
|
+
/**
|
|
3002
|
+
* `/animate-with-skeleton-v3`, beta (tier 1 subscription or higher): poses
|
|
3003
|
+
* one reference image frame-by-frame from a supplied skeleton per frame,
|
|
3004
|
+
* rather than a text motion description. Confirmed against the live
|
|
3005
|
+
* `animate_with_skeleton_v3` MCP tool schema (the same authoritative
|
|
3006
|
+
* source this codebase already treats as ground truth for the
|
|
3007
|
+
* character/object family) — `action`/`description` are both real,
|
|
3008
|
+
* optional wire fields, contrary to an initial guess that this endpoint
|
|
3009
|
+
* took no text input at all; `direction`/`keypoints`/`firstFrameKeypoints`
|
|
3010
|
+
* are required. The example keypoint from that same tool schema,
|
|
3011
|
+
* `{"label": "RIGHT KNEE", "x": 0.52, "y": 0.71, "z_index": 9}`, is what
|
|
3012
|
+
* `SkeletonKeypointSchema` (`src/skeleton.ts`) models. Same
|
|
3013
|
+
* unverified-completed-shape caveat as `animateWithTextV3`/
|
|
3014
|
+
* `animatePixminimax` above — this endpoint has never been called against
|
|
3015
|
+
* a live account by this codebase.
|
|
3016
|
+
*/
|
|
3017
|
+
async animateWithSkeletonV3(args) {
|
|
3018
|
+
const body = {
|
|
3019
|
+
first_frame: args.firstFrame,
|
|
3020
|
+
first_frame_keypoints: args.firstFrameKeypoints,
|
|
3021
|
+
keypoints: args.keypoints,
|
|
3022
|
+
direction: args.direction
|
|
3023
|
+
};
|
|
3024
|
+
if (args.templateId) body.template_id = args.templateId;
|
|
3025
|
+
if (args.action) body.action = args.action;
|
|
3026
|
+
if (args.description) body.description = args.description;
|
|
3027
|
+
if (args.seed != null) body.seed = args.seed;
|
|
3028
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
3029
|
+
return validateResponse(
|
|
3030
|
+
RevisionJobSubmitSchema,
|
|
3031
|
+
await this.request("/animate-with-skeleton-v3", { method: "POST", body: JSON.stringify(body) }),
|
|
3032
|
+
"animate-with-skeleton-v3"
|
|
3033
|
+
);
|
|
3034
|
+
}
|
|
3035
|
+
/**
|
|
3036
|
+
* `/estimate-skeleton`: auto-derives a reference image's own 18-joint
|
|
3037
|
+
* keypoints, directly usable as `animateWithSkeletonV3`'s
|
|
3038
|
+
* `firstFrameKeypoints` (or, run against a candidate pose image, as one
|
|
3039
|
+
* entry of its `keypoints` sequence). Not called anywhere in this
|
|
3040
|
+
* codebase's own submit/poll pipeline — deliberately kept outside it (see
|
|
3041
|
+
* `runEstimateSkeleton` in `src/cli/commands`) so the only PixelLab
|
|
3042
|
+
* endpoint composed into `animate-with-skeleton-v3`'s submission is that
|
|
3043
|
+
* one endpoint itself, not two unverified calls chained together.
|
|
3044
|
+
* Synchronous per this endpoint's own framing; unverified against a live
|
|
3045
|
+
* account (see `EstimateSkeletonResponseSchema`'s own caveat).
|
|
3046
|
+
*/
|
|
3047
|
+
async estimateSkeleton(args) {
|
|
3048
|
+
const body = { image: args.image };
|
|
3049
|
+
const res = validateResponse(
|
|
3050
|
+
EstimateSkeletonResponseSchema,
|
|
3051
|
+
await this.request("/estimate-skeleton", { method: "POST", body: JSON.stringify(body) }),
|
|
3052
|
+
"estimate-skeleton"
|
|
3053
|
+
);
|
|
3054
|
+
return { keypoints: res.keypoints, usage: res.usage };
|
|
3055
|
+
}
|
|
2921
3056
|
async getBackgroundJob(jobId) {
|
|
2922
3057
|
const raw = await this.request(`/background-jobs/${encodeURIComponent(jobId)}`);
|
|
2923
3058
|
return validateResponse(BackgroundJobSchema, raw, "background-jobs/{id}");
|
|
@@ -3652,6 +3787,9 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
3652
3787
|
lastFrameSha256: spec.revision.lastFrameSha256,
|
|
3653
3788
|
direction: spec.revision.direction,
|
|
3654
3789
|
enhancePrompt: spec.revision.enhancePrompt,
|
|
3790
|
+
keypointsSha256: spec.revision.keypointsSha256,
|
|
3791
|
+
skeletonTemplate: spec.revision.skeletonTemplate,
|
|
3792
|
+
description: spec.revision.description,
|
|
3655
3793
|
engine: spec.revision.engine
|
|
3656
3794
|
} : void 0
|
|
3657
3795
|
})
|
|
@@ -3740,6 +3878,18 @@ function objectProCost(spec) {
|
|
|
3740
3878
|
const south = object.reference;
|
|
3741
3879
|
return south ? proFlashObjectCost(south.width, south.height, object.directions, true) : proFlashObjectCost(spec.width, spec.height, object.directions, false);
|
|
3742
3880
|
}
|
|
3881
|
+
function animateSkeletonCost(frames) {
|
|
3882
|
+
const anchors = [[3, 2], [8, 3], [15, 4]];
|
|
3883
|
+
for (let i = 0; i < anchors.length - 1; i++) {
|
|
3884
|
+
const [lowFrames, lowCost] = anchors[i];
|
|
3885
|
+
const [highFrames, highCost] = anchors[i + 1];
|
|
3886
|
+
if (frames >= lowFrames && frames <= highFrames) {
|
|
3887
|
+
const t = (frames - lowFrames) / (highFrames - lowFrames);
|
|
3888
|
+
return lowCost + t * (highCost - lowCost);
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
return frames <= anchors[0][0] ? anchors[0][1] : anchors[anchors.length - 1][1];
|
|
3892
|
+
}
|
|
3743
3893
|
var CHARACTER_TEMPLATES = ["mannequin", "bear", "cat", "dog", "horse", "lion"];
|
|
3744
3894
|
var PRO_FLASH_TEMPLATES = [...CHARACTER_TEMPLATES, "custom"];
|
|
3745
3895
|
function encodeAnimationJob(job) {
|
|
@@ -3798,7 +3948,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3798
3948
|
* rather than a described edit — and `animate`/`animate-pixminimax`
|
|
3799
3949
|
* (`/animate-with-text-v3`, `/animate-pixminimax`), which animate any loose
|
|
3800
3950
|
* image from a text description with no character/object resource
|
|
3801
|
-
* required —
|
|
3951
|
+
* required — `animate-skeleton` (`/animate-with-skeleton-v3`, posing the
|
|
3952
|
+
* source from a supplied per-frame skeleton instead of a text description)
|
|
3953
|
+
* — and `interpolate` (`/interpolation-v2`, the in-betweens
|
|
3802
3954
|
* from one keyframe to another) and `edit-animation`
|
|
3803
3955
|
* (`/edit-animation-v2`, one text edit applied across a whole frame set).
|
|
3804
3956
|
* `outpaint` does not: there is no canvas-expansion endpoint in the API,
|
|
@@ -3806,7 +3958,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3806
3958
|
* outpaint path yet.
|
|
3807
3959
|
*/
|
|
3808
3960
|
supportsRevision(mode2) {
|
|
3809
|
-
return mode2 === "inpaint" || mode2 === "image-to-image" || mode2 === "reduce-colors" || mode2 === "correct-pixelart" || mode2 === "animate" || mode2 === "animate-pixminimax" || mode2 === "interpolate" || mode2 === "edit-animation";
|
|
3961
|
+
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";
|
|
3810
3962
|
}
|
|
3811
3963
|
/** PixelLab's own constraints: submissions must be >2s apart, and
|
|
3812
3964
|
* background jobs in flight are capped by subscription tier (Tier 1=8,
|
|
@@ -3837,6 +3989,10 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3837
3989
|
if (spec.revision?.mode === "reduce-colors" || spec.revision?.mode === "correct-pixelart") {
|
|
3838
3990
|
return { unit: "generations", amount: 0.1, candidates: 1 };
|
|
3839
3991
|
}
|
|
3992
|
+
if (spec.revision?.mode === "animate-skeleton") {
|
|
3993
|
+
const frames = spec.revision.frames ?? 8;
|
|
3994
|
+
return { unit: "generations", amount: Math.ceil(animateSkeletonCost(frames)), candidates: 1 };
|
|
3995
|
+
}
|
|
3840
3996
|
if (spec.revision?.mode === "interpolate" || spec.revision?.mode === "edit-animation") {
|
|
3841
3997
|
const width = spec.revision.sourceWidth ?? spec.width;
|
|
3842
3998
|
const height = spec.revision.sourceHeight ?? spec.height;
|
|
@@ -3918,6 +4074,18 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3918
4074
|
throw new Error(`PixelLab correct-pixelart source is ${width}x${height}; the API takes at most 1024 pixels per side`);
|
|
3919
4075
|
}
|
|
3920
4076
|
}
|
|
4077
|
+
if (spec.revision?.mode === "animate-skeleton") {
|
|
4078
|
+
const { sourceWidth: width, sourceHeight: height, frames, skeletonTemplate } = spec.revision;
|
|
4079
|
+
if (width != null && height != null && (width > 256 || height > 256)) {
|
|
4080
|
+
throw new Error(`PixelLab animate-skeleton source is ${width}x${height}; the API takes at most 256 pixels per side`);
|
|
4081
|
+
}
|
|
4082
|
+
if (frames != null && (frames < 3 || frames > 15)) {
|
|
4083
|
+
throw new Error(`PixelLab animate-skeleton takes 3 to 15 frames; the keypoints file has ${frames}`);
|
|
4084
|
+
}
|
|
4085
|
+
if (skeletonTemplate && !CHARACTER_TEMPLATES.includes(skeletonTemplate)) {
|
|
4086
|
+
throw new Error(`PixelLab animate-skeleton template "${skeletonTemplate}" is not one of ${CHARACTER_TEMPLATES.join(", ")}`);
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
3921
4089
|
if (spec.revision?.mode === "animate" || spec.revision?.mode === "animate-pixminimax") {
|
|
3922
4090
|
const { sourceWidth: width, sourceHeight: height, mode: mode2, frames, lastFrameWidth, lastFrameHeight } = spec.revision;
|
|
3923
4091
|
if (width != null && height != null && (width > 256 || height > 256)) {
|
|
@@ -5067,6 +5235,27 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
5067
5235
|
});
|
|
5068
5236
|
return { jobId: res2.background_job_id };
|
|
5069
5237
|
}
|
|
5238
|
+
if (revision.mode === "animate-skeleton") {
|
|
5239
|
+
if (!revision.keypointsFile || !revision.keypointsSha256 || !revision.skeleton) {
|
|
5240
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision keypoints are not ready`);
|
|
5241
|
+
}
|
|
5242
|
+
const keypointsBytes = (0, import_node_fs2.readFileSync)(revision.keypointsFile);
|
|
5243
|
+
if (sha256(keypointsBytes) !== revision.keypointsSha256) {
|
|
5244
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision keypoints changed after the manifest was resolved`);
|
|
5245
|
+
}
|
|
5246
|
+
const res2 = await this.client.animateWithSkeletonV3({
|
|
5247
|
+
firstFrame: image,
|
|
5248
|
+
firstFrameKeypoints: revision.skeleton.firstFrameKeypoints,
|
|
5249
|
+
keypoints: revision.skeleton.frames,
|
|
5250
|
+
direction: revision.direction,
|
|
5251
|
+
templateId: revision.skeletonTemplate,
|
|
5252
|
+
action: spec.prompt,
|
|
5253
|
+
description: revision.description,
|
|
5254
|
+
seed: spec.seed,
|
|
5255
|
+
noBackground: spec.noBackground
|
|
5256
|
+
});
|
|
5257
|
+
return { jobId: res2.background_job_id };
|
|
5258
|
+
}
|
|
5070
5259
|
if (revision.strength != null) {
|
|
5071
5260
|
throw new Error(
|
|
5072
5261
|
`${spec.styleId}/${spec.assetId}: PixelLab image-to-image revisions take no strength; edit-images-v2 always applies the full instruction`
|
|
@@ -5132,7 +5321,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
5132
5321
|
if (revisionMode === "reduce-colors" || revisionMode === "correct-pixelart") {
|
|
5133
5322
|
return this.pollCachedRevision(jobId, context);
|
|
5134
5323
|
}
|
|
5135
|
-
if (revisionMode === "animate" || revisionMode === "animate-pixminimax" || revisionMode === "interpolate" || revisionMode === "edit-animation") {
|
|
5324
|
+
if (revisionMode === "animate" || revisionMode === "animate-pixminimax" || revisionMode === "animate-skeleton" || revisionMode === "interpolate" || revisionMode === "edit-animation") {
|
|
5136
5325
|
return this.pollAnimateRevision(jobId, context);
|
|
5137
5326
|
}
|
|
5138
5327
|
if (context?.spec?.revision) return this.pollRevision(jobId);
|
|
@@ -6867,11 +7056,12 @@ var ComfyUIProvider = class _ComfyUIProvider {
|
|
|
6867
7056
|
/**
|
|
6868
7057
|
* Everything else resolves generically to whatever the user's own
|
|
6869
7058
|
* workflow does with `bindings.sourceImage`. The frame-set modes
|
|
6870
|
-
* (`animate`, `animate-pixminimax`, `
|
|
6871
|
-
* the exception: they produce an ordered frame set,
|
|
6872
|
-
* revision path always writes a single output image
|
|
6873
|
-
* below) — a real structural gap, not a missing
|
|
6874
|
-
* rejected here rather than only failing once
|
|
7059
|
+
* (`animate`, `animate-pixminimax`, `animate-skeleton`, `interpolate`,
|
|
7060
|
+
* `edit-animation`) are the exception: they produce an ordered frame set,
|
|
7061
|
+
* and this adapter's revision path always writes a single output image
|
|
7062
|
+
* (see `submit`/`fetch` below) — a real structural gap, not a missing
|
|
7063
|
+
* binding, so they are rejected here rather than only failing once
|
|
7064
|
+
* `validate` runs.
|
|
6875
7065
|
*/
|
|
6876
7066
|
supportsRevision(mode2) {
|
|
6877
7067
|
return !FRAME_SET_REVISION_MODES.includes(mode2);
|
|
@@ -8774,6 +8964,8 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8774
8964
|
const paletteImage = paletteImageFile ? await optionalRevisionImage(paletteImageFile, "revision palette image", "png") : null;
|
|
8775
8965
|
const lastFrameFile = asset.revision.lastFrame ? import_node_path5.default.resolve(root, asset.revision.lastFrame) : void 0;
|
|
8776
8966
|
const lastFrame = lastFrameFile ? await optionalRevisionImage(lastFrameFile, "revision last frame") : null;
|
|
8967
|
+
const keypointsFile = asset.revision.keypointsFile ? import_node_path5.default.resolve(root, asset.revision.keypointsFile) : void 0;
|
|
8968
|
+
const keypoints = keypointsFile ? await optionalSkeletonSet(keypointsFile) : null;
|
|
8777
8969
|
resolved.revision = {
|
|
8778
8970
|
mode: asset.revision.mode,
|
|
8779
8971
|
sourceAssetId: asset.revision.from,
|
|
@@ -8814,6 +9006,18 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8814
9006
|
} : {},
|
|
8815
9007
|
...asset.revision.direction ? { direction: asset.revision.direction } : {},
|
|
8816
9008
|
...asset.revision.enhancePrompt == null ? {} : { enhancePrompt: asset.revision.enhancePrompt },
|
|
9009
|
+
...keypointsFile ? {
|
|
9010
|
+
keypointsFile,
|
|
9011
|
+
keypointsSha256: keypoints?.hash ?? null,
|
|
9012
|
+
skeleton: keypoints?.skeleton ?? null,
|
|
9013
|
+
// The manifest's own `frames` field stays rejected for this
|
|
9014
|
+
// mode (superRefine, types.ts) — the real frame count comes
|
|
9015
|
+
// from the keypoints file once it exists, not a manifest
|
|
9016
|
+
// number, so plan can only know it once authored.
|
|
9017
|
+
...keypoints ? { frames: keypoints.skeleton.frames.length } : {}
|
|
9018
|
+
} : {},
|
|
9019
|
+
...asset.revision.skeletonTemplate ? { skeletonTemplate: asset.revision.skeletonTemplate } : {},
|
|
9020
|
+
...asset.revision.description ? { description: asset.revision.description } : {},
|
|
8817
9021
|
...asset.revision.engine ? { engine: asset.revision.engine } : {}
|
|
8818
9022
|
};
|
|
8819
9023
|
}
|
|
@@ -8935,6 +9139,17 @@ async function optionalRevisionImage(file, label, requiredFormat) {
|
|
|
8935
9139
|
}
|
|
8936
9140
|
return { hash: sha256(bytes), ...metadata };
|
|
8937
9141
|
}
|
|
9142
|
+
async function optionalSkeletonSet(file) {
|
|
9143
|
+
if (!(0, import_node_fs5.existsSync)(file)) return null;
|
|
9144
|
+
const bytes = await (0, import_promises3.readFile)(file);
|
|
9145
|
+
let json;
|
|
9146
|
+
try {
|
|
9147
|
+
json = JSON.parse(bytes.toString("utf8"));
|
|
9148
|
+
} catch (error) {
|
|
9149
|
+
throw new Error(`revision keypoints file ${file} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
9150
|
+
}
|
|
9151
|
+
return { hash: sha256(bytes), skeleton: parseSkeletonSet(json, file) };
|
|
9152
|
+
}
|
|
8938
9153
|
async function revisionSourceMembers(stem, label) {
|
|
8939
9154
|
if ((0, import_node_fs5.existsSync)(stem)) return null;
|
|
8940
9155
|
const at = (role) => memberPath(stem, role, 0, 2, MediaType.PNG);
|
|
@@ -11057,47 +11272,47 @@ var import_node_path14 = __toESM(require("path"), 1);
|
|
|
11057
11272
|
var import_node_fs10 = require("fs");
|
|
11058
11273
|
var import_promises7 = require("fs/promises");
|
|
11059
11274
|
var import_node_url = require("url");
|
|
11060
|
-
var
|
|
11275
|
+
var import_zod4 = require("zod");
|
|
11061
11276
|
var SHA256_RE = /^[0-9a-f]{64}$/;
|
|
11062
11277
|
var RECIPE_ID_RE = /^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/;
|
|
11063
11278
|
var VERSION_RE = /^\d+\.\d+\.\d+$/;
|
|
11064
11279
|
var RECIPE_FILE = "pixelkiln.recipe.json";
|
|
11065
11280
|
var RECIPE_DIR_TOKEN = "{{recipeDir}}";
|
|
11066
|
-
var PortablePathSchema =
|
|
11281
|
+
var PortablePathSchema = import_zod4.z.string().min(1).refine((value) => {
|
|
11067
11282
|
if (value.includes("\\") || import_node_path14.default.posix.isAbsolute(value)) return false;
|
|
11068
11283
|
const parts = value.split("/");
|
|
11069
11284
|
return !parts.includes("") && !parts.includes(".") && !parts.includes("..");
|
|
11070
11285
|
}, "expected a portable relative path without '.', '..', or backslashes");
|
|
11071
|
-
var RecipeBindingSchema =
|
|
11072
|
-
nodeId:
|
|
11073
|
-
input:
|
|
11286
|
+
var RecipeBindingSchema = import_zod4.z.object({
|
|
11287
|
+
nodeId: import_zod4.z.string().min(1),
|
|
11288
|
+
input: import_zod4.z.string().min(1)
|
|
11074
11289
|
}).strict();
|
|
11075
|
-
var RecipeSchema =
|
|
11076
|
-
$schema:
|
|
11077
|
-
format:
|
|
11078
|
-
schemaVersion:
|
|
11079
|
-
id:
|
|
11080
|
-
version:
|
|
11081
|
-
provider:
|
|
11082
|
-
summary:
|
|
11083
|
-
files:
|
|
11290
|
+
var RecipeSchema = import_zod4.z.object({
|
|
11291
|
+
$schema: import_zod4.z.string().url().optional(),
|
|
11292
|
+
format: import_zod4.z.literal("pixelkiln-recipe"),
|
|
11293
|
+
schemaVersion: import_zod4.z.literal(1),
|
|
11294
|
+
id: import_zod4.z.string().regex(RECIPE_ID_RE, "expected provider/name"),
|
|
11295
|
+
version: import_zod4.z.string().regex(VERSION_RE, "expected x.y.z"),
|
|
11296
|
+
provider: import_zod4.z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
11297
|
+
summary: import_zod4.z.string().min(1).max(240),
|
|
11298
|
+
files: import_zod4.z.array(import_zod4.z.object({
|
|
11084
11299
|
path: PortablePathSchema,
|
|
11085
|
-
role:
|
|
11086
|
-
sha256:
|
|
11300
|
+
role: import_zod4.z.enum(["workflow", "reference"]),
|
|
11301
|
+
sha256: import_zod4.z.string().regex(SHA256_RE)
|
|
11087
11302
|
}).strict()).default([]),
|
|
11088
|
-
models:
|
|
11303
|
+
models: import_zod4.z.array(import_zod4.z.object({
|
|
11089
11304
|
path: PortablePathSchema,
|
|
11090
|
-
sha256:
|
|
11091
|
-
source:
|
|
11092
|
-
license:
|
|
11305
|
+
sha256: import_zod4.z.string().regex(SHA256_RE),
|
|
11306
|
+
source: import_zod4.z.string().url(),
|
|
11307
|
+
license: import_zod4.z.string().min(1)
|
|
11093
11308
|
}).strict()).default([]),
|
|
11094
|
-
styleId:
|
|
11309
|
+
styleId: import_zod4.z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
11095
11310
|
style: StyleSchema,
|
|
11096
|
-
workflow:
|
|
11311
|
+
workflow: import_zod4.z.object({
|
|
11097
11312
|
path: PortablePathSchema,
|
|
11098
|
-
outputNodeId:
|
|
11099
|
-
numImages:
|
|
11100
|
-
bindings:
|
|
11313
|
+
outputNodeId: import_zod4.z.string().min(1),
|
|
11314
|
+
numImages: import_zod4.z.number().int().min(1).max(16),
|
|
11315
|
+
bindings: import_zod4.z.object({
|
|
11101
11316
|
prompt: RecipeBindingSchema,
|
|
11102
11317
|
width: RecipeBindingSchema.optional(),
|
|
11103
11318
|
height: RecipeBindingSchema.optional(),
|
|
@@ -11108,67 +11323,67 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11108
11323
|
strength: RecipeBindingSchema.optional()
|
|
11109
11324
|
}).strict()
|
|
11110
11325
|
}).strict().optional(),
|
|
11111
|
-
quality:
|
|
11112
|
-
stage:
|
|
11113
|
-
workingCanvas:
|
|
11114
|
-
width:
|
|
11115
|
-
height:
|
|
11326
|
+
quality: import_zod4.z.object({
|
|
11327
|
+
stage: import_zod4.z.enum(["composition-source", "production-candidate"]),
|
|
11328
|
+
workingCanvas: import_zod4.z.object({
|
|
11329
|
+
width: import_zod4.z.number().int().min(16),
|
|
11330
|
+
height: import_zod4.z.number().int().min(16)
|
|
11116
11331
|
}).strict(),
|
|
11117
|
-
recommendedNativeSize:
|
|
11118
|
-
min:
|
|
11119
|
-
max:
|
|
11332
|
+
recommendedNativeSize: import_zod4.z.object({
|
|
11333
|
+
min: import_zod4.z.number().int().min(1),
|
|
11334
|
+
max: import_zod4.z.number().int().min(1)
|
|
11120
11335
|
}).strict(),
|
|
11121
|
-
paletteColors:
|
|
11122
|
-
min:
|
|
11123
|
-
max:
|
|
11336
|
+
paletteColors: import_zod4.z.object({
|
|
11337
|
+
min: import_zod4.z.number().int().min(1),
|
|
11338
|
+
max: import_zod4.z.number().int().min(1)
|
|
11124
11339
|
}).strict(),
|
|
11125
|
-
background:
|
|
11126
|
-
checks:
|
|
11340
|
+
background: import_zod4.z.enum(["opaque", "transparent", "full-bleed"]),
|
|
11341
|
+
checks: import_zod4.z.array(import_zod4.z.enum([
|
|
11127
11342
|
"prompt-coverage",
|
|
11128
11343
|
"native-grid",
|
|
11129
11344
|
"final-palette",
|
|
11130
11345
|
"alpha-edge",
|
|
11131
11346
|
"human-1x"
|
|
11132
11347
|
])).min(1),
|
|
11133
|
-
notes:
|
|
11348
|
+
notes: import_zod4.z.array(import_zod4.z.string().min(1)).default([])
|
|
11134
11349
|
}).strict(),
|
|
11135
|
-
integrity:
|
|
11136
|
-
algorithm:
|
|
11137
|
-
digest:
|
|
11350
|
+
integrity: import_zod4.z.object({
|
|
11351
|
+
algorithm: import_zod4.z.literal("sha256"),
|
|
11352
|
+
digest: import_zod4.z.string().regex(SHA256_RE)
|
|
11138
11353
|
}).strict()
|
|
11139
11354
|
}).strict().superRefine((recipe, context) => {
|
|
11140
11355
|
if (recipe.style.provider && recipe.style.provider !== recipe.provider) {
|
|
11141
11356
|
context.addIssue({
|
|
11142
|
-
code:
|
|
11357
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11143
11358
|
path: ["style", "provider"],
|
|
11144
11359
|
message: "must match the recipe provider"
|
|
11145
11360
|
});
|
|
11146
11361
|
}
|
|
11147
11362
|
const filePaths = recipe.files.map((file) => file.path);
|
|
11148
11363
|
if (new Set(filePaths).size !== filePaths.length) {
|
|
11149
|
-
context.addIssue({ code:
|
|
11364
|
+
context.addIssue({ code: import_zod4.z.ZodIssueCode.custom, path: ["files"], message: "duplicate file path" });
|
|
11150
11365
|
}
|
|
11151
11366
|
const modelPaths = recipe.models.map((model) => model.path);
|
|
11152
11367
|
if (new Set(modelPaths).size !== modelPaths.length) {
|
|
11153
|
-
context.addIssue({ code:
|
|
11368
|
+
context.addIssue({ code: import_zod4.z.ZodIssueCode.custom, path: ["models"], message: "duplicate model path" });
|
|
11154
11369
|
}
|
|
11155
11370
|
if (filePaths.includes(RECIPE_FILE)) {
|
|
11156
11371
|
context.addIssue({
|
|
11157
|
-
code:
|
|
11372
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11158
11373
|
path: ["files"],
|
|
11159
11374
|
message: `${RECIPE_FILE} cannot hash itself`
|
|
11160
11375
|
});
|
|
11161
11376
|
}
|
|
11162
11377
|
if (recipe.quality.recommendedNativeSize.min > recipe.quality.recommendedNativeSize.max) {
|
|
11163
11378
|
context.addIssue({
|
|
11164
|
-
code:
|
|
11379
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11165
11380
|
path: ["quality", "recommendedNativeSize"],
|
|
11166
11381
|
message: "min cannot exceed max"
|
|
11167
11382
|
});
|
|
11168
11383
|
}
|
|
11169
11384
|
if (recipe.quality.paletteColors.min > recipe.quality.paletteColors.max) {
|
|
11170
11385
|
context.addIssue({
|
|
11171
|
-
code:
|
|
11386
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11172
11387
|
path: ["quality", "paletteColors"],
|
|
11173
11388
|
message: "min cannot exceed max"
|
|
11174
11389
|
});
|
|
@@ -11177,7 +11392,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11177
11392
|
(file) => file.path === recipe.workflow.path && file.role === "workflow"
|
|
11178
11393
|
)) {
|
|
11179
11394
|
context.addIssue({
|
|
11180
|
-
code:
|
|
11395
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11181
11396
|
path: ["workflow", "path"],
|
|
11182
11397
|
message: "must name a file whose role is workflow"
|
|
11183
11398
|
});
|
|
@@ -11185,7 +11400,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11185
11400
|
if (recipe.provider === "comfyui") {
|
|
11186
11401
|
if (!recipe.workflow) {
|
|
11187
11402
|
context.addIssue({
|
|
11188
|
-
code:
|
|
11403
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11189
11404
|
path: ["workflow"],
|
|
11190
11405
|
message: "ComfyUI recipes require workflow metadata"
|
|
11191
11406
|
});
|
|
@@ -11194,7 +11409,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11194
11409
|
const options = recipe.style.providerOptions.comfyui;
|
|
11195
11410
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
11196
11411
|
context.addIssue({
|
|
11197
|
-
code:
|
|
11412
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11198
11413
|
path: ["style", "providerOptions", "comfyui"],
|
|
11199
11414
|
message: "ComfyUI recipes require ComfyUI provider options"
|
|
11200
11415
|
});
|
|
@@ -11208,7 +11423,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11208
11423
|
};
|
|
11209
11424
|
if (JSON.stringify(canonical3(options)) !== JSON.stringify(canonical3(expected))) {
|
|
11210
11425
|
context.addIssue({
|
|
11211
|
-
code:
|
|
11426
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11212
11427
|
path: ["style", "providerOptions", "comfyui"],
|
|
11213
11428
|
message: "must match workflow metadata and use {{recipeDir}} for workflowFile"
|
|
11214
11429
|
});
|
|
@@ -11646,11 +11861,11 @@ async function generateFont(client2, opts) {
|
|
|
11646
11861
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
11647
11862
|
var import_node_fs13 = require("fs");
|
|
11648
11863
|
var import_promises10 = require("fs/promises");
|
|
11649
|
-
var
|
|
11864
|
+
var import_zod5 = require("zod");
|
|
11650
11865
|
var SHA256_RE2 = /^[0-9a-f]{64}$/;
|
|
11651
11866
|
var HEX_RE = /^#[0-9a-f]{6}$/;
|
|
11652
11867
|
var MAX_REDMEAN_DISTANCE = 765;
|
|
11653
|
-
var QualityPathSchema =
|
|
11868
|
+
var QualityPathSchema = import_zod5.z.string().min(1).refine(
|
|
11654
11869
|
(value) => !import_node_path17.default.posix.isAbsolute(value) && !value.includes("\\"),
|
|
11655
11870
|
"expected a portable relative path"
|
|
11656
11871
|
);
|
|
@@ -11664,53 +11879,53 @@ var DEFAULT_QUALITY_TOLERANCES = {
|
|
|
11664
11879
|
maxEdgeContrastDrop: 0.03,
|
|
11665
11880
|
maxIsolatedPixelIncrease: 5e-3
|
|
11666
11881
|
};
|
|
11667
|
-
var QualityToleranceSchema =
|
|
11668
|
-
requireExactHash:
|
|
11669
|
-
maxColorCountIncrease:
|
|
11670
|
-
maxNewColors:
|
|
11671
|
-
maxTransparencyDelta:
|
|
11672
|
-
maxPartialAlphaIncrease:
|
|
11673
|
-
maxEdgeDensityDelta:
|
|
11674
|
-
maxEdgeContrastDrop:
|
|
11675
|
-
maxIsolatedPixelIncrease:
|
|
11882
|
+
var QualityToleranceSchema = import_zod5.z.object({
|
|
11883
|
+
requireExactHash: import_zod5.z.boolean(),
|
|
11884
|
+
maxColorCountIncrease: import_zod5.z.number().int().min(0),
|
|
11885
|
+
maxNewColors: import_zod5.z.number().int().min(0),
|
|
11886
|
+
maxTransparencyDelta: import_zod5.z.number().min(0).max(1),
|
|
11887
|
+
maxPartialAlphaIncrease: import_zod5.z.number().min(0).max(1),
|
|
11888
|
+
maxEdgeDensityDelta: import_zod5.z.number().min(0).max(1),
|
|
11889
|
+
maxEdgeContrastDrop: import_zod5.z.number().min(0).max(1),
|
|
11890
|
+
maxIsolatedPixelIncrease: import_zod5.z.number().min(0).max(1)
|
|
11676
11891
|
}).strict();
|
|
11677
|
-
var ImageQualityMetricsSchema =
|
|
11678
|
-
sha256:
|
|
11679
|
-
width:
|
|
11680
|
-
height:
|
|
11681
|
-
colorCount:
|
|
11682
|
-
colors:
|
|
11683
|
-
transparency:
|
|
11684
|
-
partialAlpha:
|
|
11685
|
-
edgeDensity:
|
|
11686
|
-
meanEdgeContrast:
|
|
11687
|
-
isolatedPixelRatio:
|
|
11892
|
+
var ImageQualityMetricsSchema = import_zod5.z.object({
|
|
11893
|
+
sha256: import_zod5.z.string().regex(SHA256_RE2),
|
|
11894
|
+
width: import_zod5.z.number().int().min(1),
|
|
11895
|
+
height: import_zod5.z.number().int().min(1),
|
|
11896
|
+
colorCount: import_zod5.z.number().int().min(0),
|
|
11897
|
+
colors: import_zod5.z.array(import_zod5.z.string().regex(HEX_RE)),
|
|
11898
|
+
transparency: import_zod5.z.number().min(0).max(1),
|
|
11899
|
+
partialAlpha: import_zod5.z.number().min(0).max(1),
|
|
11900
|
+
edgeDensity: import_zod5.z.number().min(0).max(1),
|
|
11901
|
+
meanEdgeContrast: import_zod5.z.number().min(0).max(1),
|
|
11902
|
+
isolatedPixelRatio: import_zod5.z.number().min(0).max(1)
|
|
11688
11903
|
}).strict();
|
|
11689
|
-
var QualityBaselineCaseSchema =
|
|
11690
|
-
id:
|
|
11904
|
+
var QualityBaselineCaseSchema = import_zod5.z.object({
|
|
11905
|
+
id: import_zod5.z.string().regex(/^[a-z0-9][a-z0-9/_-]*$/),
|
|
11691
11906
|
file: QualityPathSchema,
|
|
11692
|
-
record:
|
|
11907
|
+
record: import_zod5.z.object({
|
|
11693
11908
|
path: QualityPathSchema,
|
|
11694
|
-
sha256:
|
|
11909
|
+
sha256: import_zod5.z.string().regex(SHA256_RE2)
|
|
11695
11910
|
}).strict().optional(),
|
|
11696
11911
|
expected: ImageQualityMetricsSchema,
|
|
11697
11912
|
tolerances: QualityToleranceSchema
|
|
11698
11913
|
}).strict();
|
|
11699
|
-
var QualityBaselineSchema =
|
|
11700
|
-
$schema:
|
|
11701
|
-
format:
|
|
11702
|
-
schemaVersion:
|
|
11703
|
-
cases:
|
|
11914
|
+
var QualityBaselineSchema = import_zod5.z.object({
|
|
11915
|
+
$schema: import_zod5.z.string().url().optional(),
|
|
11916
|
+
format: import_zod5.z.literal("pixelkiln-quality-baseline"),
|
|
11917
|
+
schemaVersion: import_zod5.z.literal(1),
|
|
11918
|
+
cases: import_zod5.z.array(QualityBaselineCaseSchema).min(1)
|
|
11704
11919
|
}).strict().superRefine((baseline, context) => {
|
|
11705
11920
|
const ids = baseline.cases.map((entry) => entry.id);
|
|
11706
11921
|
if (new Set(ids).size !== ids.length) {
|
|
11707
|
-
context.addIssue({ code:
|
|
11922
|
+
context.addIssue({ code: import_zod5.z.ZodIssueCode.custom, path: ["cases"], message: "duplicate case id" });
|
|
11708
11923
|
}
|
|
11709
11924
|
});
|
|
11710
|
-
var QualityInputSchema =
|
|
11711
|
-
id:
|
|
11712
|
-
path:
|
|
11713
|
-
record:
|
|
11925
|
+
var QualityInputSchema = import_zod5.z.object({
|
|
11926
|
+
id: import_zod5.z.string().regex(/^[a-z0-9][a-z0-9/_-]*$/),
|
|
11927
|
+
path: import_zod5.z.string().min(1),
|
|
11928
|
+
record: import_zod5.z.string().min(1).optional(),
|
|
11714
11929
|
tolerances: QualityToleranceSchema.partial().optional()
|
|
11715
11930
|
}).strict();
|
|
11716
11931
|
function message4(error) {
|
|
@@ -11812,7 +12027,7 @@ async function measureImageQuality(file) {
|
|
|
11812
12027
|
}
|
|
11813
12028
|
}
|
|
11814
12029
|
function resolveQualityInputs(raw, inputsFilePath) {
|
|
11815
|
-
const parsed =
|
|
12030
|
+
const parsed = import_zod5.z.array(QualityInputSchema).min(1).safeParse(raw);
|
|
11816
12031
|
if (!parsed.success) {
|
|
11817
12032
|
throw new Error(
|
|
11818
12033
|
"--inputs must be a non-empty JSON array of quality cases:\n" + parsed.error.issues.map((issue) => ` ${issue.path.join(".") || "$"}: ${issue.message}`).join("\n")
|
|
@@ -12035,11 +12250,11 @@ var import_node_path21 = __toESM(require("path"), 1);
|
|
|
12035
12250
|
var import_promises11 = require("fs/promises");
|
|
12036
12251
|
var import_node_fs14 = require("fs");
|
|
12037
12252
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
12038
|
-
var
|
|
12039
|
-
var HashCacheSchema =
|
|
12040
|
-
version:
|
|
12253
|
+
var import_zod6 = require("zod");
|
|
12254
|
+
var HashCacheSchema = import_zod6.z.object({
|
|
12255
|
+
version: import_zod6.z.literal(1),
|
|
12041
12256
|
/** objectId → sha256 of that object's image bytes. */
|
|
12042
|
-
hashes:
|
|
12257
|
+
hashes: import_zod6.z.record(import_zod6.z.string())
|
|
12043
12258
|
});
|
|
12044
12259
|
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
12045
12260
|
function isSha256Hash(value) {
|
|
@@ -13587,6 +13802,9 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13587
13802
|
...spec.revision.lastFrameSha256 ? { lastFrameSha256: spec.revision.lastFrameSha256 } : {},
|
|
13588
13803
|
...spec.revision.direction ? { direction: spec.revision.direction } : {},
|
|
13589
13804
|
...spec.revision.enhancePrompt == null ? {} : { enhancePrompt: spec.revision.enhancePrompt },
|
|
13805
|
+
...spec.revision.keypointsSha256 ? { keypointsSha256: spec.revision.keypointsSha256 } : {},
|
|
13806
|
+
...spec.revision.skeletonTemplate ? { skeletonTemplate: spec.revision.skeletonTemplate } : {},
|
|
13807
|
+
...spec.revision.description ? { description: spec.revision.description } : {},
|
|
13590
13808
|
...spec.revision.engine ? { engine: spec.revision.engine } : {}
|
|
13591
13809
|
} : null,
|
|
13592
13810
|
outfit: spec.character?.kind === "outfit" && outfitParentEntry ? {
|
|
@@ -14884,20 +15102,20 @@ var import_node_path30 = __toESM(require("path"), 1);
|
|
|
14884
15102
|
var import_promises19 = require("fs/promises");
|
|
14885
15103
|
var import_node_fs23 = require("fs");
|
|
14886
15104
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
14887
|
-
var
|
|
14888
|
-
var WorkspaceProjectSchema =
|
|
14889
|
-
id:
|
|
15105
|
+
var import_zod7 = require("zod");
|
|
15106
|
+
var WorkspaceProjectSchema = import_zod7.z.object({
|
|
15107
|
+
id: import_zod7.z.string().min(1),
|
|
14890
15108
|
/** Manifest path, relative to the catalog file's own directory. */
|
|
14891
|
-
manifest:
|
|
15109
|
+
manifest: import_zod7.z.string().min(1),
|
|
14892
15110
|
/** Lockfile path, relative to the catalog file's own directory. */
|
|
14893
|
-
lock:
|
|
14894
|
-
provider:
|
|
15111
|
+
lock: import_zod7.z.string().min(1),
|
|
15112
|
+
provider: import_zod7.z.string().min(1).default("pixellab"),
|
|
14895
15113
|
/** Free-form label for a shared account, e.g. distinguishing sandboxes. */
|
|
14896
|
-
account:
|
|
15114
|
+
account: import_zod7.z.string().optional()
|
|
14897
15115
|
}).strict();
|
|
14898
|
-
var WorkspaceSchema =
|
|
14899
|
-
version:
|
|
14900
|
-
projects:
|
|
15116
|
+
var WorkspaceSchema = import_zod7.z.object({
|
|
15117
|
+
version: import_zod7.z.literal(1),
|
|
15118
|
+
projects: import_zod7.z.array(WorkspaceProjectSchema).default([])
|
|
14901
15119
|
}).strict();
|
|
14902
15120
|
function parseWorkspace(raw) {
|
|
14903
15121
|
const parsed = WorkspaceSchema.safeParse(raw);
|
|
@@ -15015,62 +15233,62 @@ function validateWorkspace(ws, dir) {
|
|
|
15015
15233
|
|
|
15016
15234
|
// src/gallery/edit.ts
|
|
15017
15235
|
var import_node_path29 = __toESM(require("path"), 1);
|
|
15018
|
-
var
|
|
15236
|
+
var import_zod10 = require("zod");
|
|
15019
15237
|
|
|
15020
15238
|
// src/manifest-edit.ts
|
|
15021
15239
|
var import_promises20 = require("fs/promises");
|
|
15022
15240
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
15023
|
-
var
|
|
15024
|
-
var HexSha =
|
|
15025
|
-
var AssetPatchSchema =
|
|
15026
|
-
prompt:
|
|
15241
|
+
var import_zod8 = require("zod");
|
|
15242
|
+
var HexSha = import_zod8.z.string().regex(/^[0-9a-f]{64}$/);
|
|
15243
|
+
var AssetPatchSchema = import_zod8.z.object({
|
|
15244
|
+
prompt: import_zod8.z.string().optional(),
|
|
15027
15245
|
/** Per-style override for the style being viewed; null removes it. */
|
|
15028
|
-
promptForStyle:
|
|
15029
|
-
category:
|
|
15030
|
-
width:
|
|
15031
|
-
height:
|
|
15032
|
-
size:
|
|
15033
|
-
tags:
|
|
15246
|
+
promptForStyle: import_zod8.z.object({ styleId: import_zod8.z.string().min(1), prompt: import_zod8.z.string().nullable() }).optional(),
|
|
15247
|
+
category: import_zod8.z.string().nullable().optional(),
|
|
15248
|
+
width: import_zod8.z.number().int().nullable().optional(),
|
|
15249
|
+
height: import_zod8.z.number().int().nullable().optional(),
|
|
15250
|
+
size: import_zod8.z.number().int().nullable().optional(),
|
|
15251
|
+
tags: import_zod8.z.array(import_zod8.z.string()).optional()
|
|
15034
15252
|
}).strict();
|
|
15035
|
-
var NewStateSchema =
|
|
15253
|
+
var NewStateSchema = import_zod8.z.object({
|
|
15036
15254
|
/** Asset id of the parent this states; must already exist. */
|
|
15037
|
-
of:
|
|
15038
|
-
paletteFromReference:
|
|
15039
|
-
canvas:
|
|
15255
|
+
of: import_zod8.z.string().min(1),
|
|
15256
|
+
paletteFromReference: import_zod8.z.boolean().optional(),
|
|
15257
|
+
canvas: import_zod8.z.object({ width: import_zod8.z.number().int().min(16).max(256), height: import_zod8.z.number().int().min(16).max(256) }).strict().optional()
|
|
15040
15258
|
}).strict();
|
|
15041
|
-
var NewAnimationSchema =
|
|
15259
|
+
var NewAnimationSchema = import_zod8.z.object({
|
|
15042
15260
|
/** Asset id of the parent this animates; must already exist. */
|
|
15043
|
-
of:
|
|
15261
|
+
of: import_zod8.z.string().min(1),
|
|
15044
15262
|
/** A PixelLab template id (`character` only; `objectPro` has no template concept). */
|
|
15045
|
-
template:
|
|
15263
|
+
template: import_zod8.z.string().min(1).optional(),
|
|
15046
15264
|
direction: CharacterDirectionSchema.optional(),
|
|
15047
|
-
frames:
|
|
15048
|
-
fps:
|
|
15265
|
+
frames: import_zod8.z.number().int().min(4).max(16).optional(),
|
|
15266
|
+
fps: import_zod8.z.number().int().min(1).max(60).optional(),
|
|
15049
15267
|
mode: CharacterAnimationModeSchema.optional(),
|
|
15050
15268
|
/** What is being animated, when the parent's own description would mislead the model (`character` only). */
|
|
15051
|
-
subject:
|
|
15052
|
-
enhancePrompt:
|
|
15269
|
+
subject: import_zod8.z.string().min(1).optional(),
|
|
15270
|
+
enhancePrompt: import_zod8.z.boolean().optional()
|
|
15053
15271
|
}).strict();
|
|
15054
|
-
var NewAssetSchema =
|
|
15055
|
-
prompt:
|
|
15056
|
-
category:
|
|
15057
|
-
width:
|
|
15058
|
-
height:
|
|
15059
|
-
size:
|
|
15060
|
-
tags:
|
|
15272
|
+
var NewAssetSchema = import_zod8.z.object({
|
|
15273
|
+
prompt: import_zod8.z.string(),
|
|
15274
|
+
category: import_zod8.z.string().optional(),
|
|
15275
|
+
width: import_zod8.z.number().int().optional(),
|
|
15276
|
+
height: import_zod8.z.number().int().optional(),
|
|
15277
|
+
size: import_zod8.z.number().int().optional(),
|
|
15278
|
+
tags: import_zod8.z.array(import_zod8.z.string()).optional(),
|
|
15061
15279
|
/** Restrict to these styles; empty or omitted means every style. */
|
|
15062
|
-
styles:
|
|
15280
|
+
styles: import_zod8.z.array(import_zod8.z.string().min(1)).optional(),
|
|
15063
15281
|
/**
|
|
15064
15282
|
* A controlled regeneration of another asset in the same manifest,
|
|
15065
15283
|
* instead of a fresh generation. `inpaint` needs a mask upload the
|
|
15066
15284
|
* gallery does not offer yet, so only `image-to-image` can be created
|
|
15067
15285
|
* here; hand-edit the manifest for the other modes.
|
|
15068
15286
|
*/
|
|
15069
|
-
revision:
|
|
15070
|
-
mode:
|
|
15287
|
+
revision: import_zod8.z.object({
|
|
15288
|
+
mode: import_zod8.z.literal("image-to-image"),
|
|
15071
15289
|
/** Asset id of the parent this revises; must already exist. */
|
|
15072
|
-
from:
|
|
15073
|
-
strength:
|
|
15290
|
+
from: import_zod8.z.string().min(1),
|
|
15291
|
+
strength: import_zod8.z.number().min(0).max(1).optional()
|
|
15074
15292
|
}).strict().optional(),
|
|
15075
15293
|
/** A pose or outfit of an existing `character`/`objectPro` base or state. */
|
|
15076
15294
|
state: NewStateSchema.optional(),
|
|
@@ -15086,58 +15304,58 @@ var CANDIDATE_OPTION = {
|
|
|
15086
15304
|
comfyui: "numImages",
|
|
15087
15305
|
scenario: "numOutputs"
|
|
15088
15306
|
};
|
|
15089
|
-
var ManifestEditSchema =
|
|
15090
|
-
|
|
15091
|
-
action:
|
|
15307
|
+
var ManifestEditSchema = import_zod8.z.discriminatedUnion("action", [
|
|
15308
|
+
import_zod8.z.object({
|
|
15309
|
+
action: import_zod8.z.literal("patch-asset"),
|
|
15092
15310
|
/** Workspace project id; omitted for a single-project gallery. */
|
|
15093
|
-
project:
|
|
15094
|
-
assetId:
|
|
15311
|
+
project: import_zod8.z.string().min(1).optional(),
|
|
15312
|
+
assetId: import_zod8.z.string().min(1),
|
|
15095
15313
|
/** Manifest bytes the page last saw; a mismatch refuses the write. */
|
|
15096
15314
|
expectedSha256: HexSha,
|
|
15097
15315
|
patch: AssetPatchSchema
|
|
15098
15316
|
}).strict(),
|
|
15099
|
-
|
|
15100
|
-
action:
|
|
15101
|
-
project:
|
|
15102
|
-
assetId:
|
|
15317
|
+
import_zod8.z.object({
|
|
15318
|
+
action: import_zod8.z.literal("add-asset"),
|
|
15319
|
+
project: import_zod8.z.string().min(1).optional(),
|
|
15320
|
+
assetId: import_zod8.z.string().min(1).regex(/^[^/\\]+$/, "asset ids cannot contain slashes"),
|
|
15103
15321
|
expectedSha256: HexSha,
|
|
15104
15322
|
asset: NewAssetSchema
|
|
15105
15323
|
}).strict(),
|
|
15106
|
-
|
|
15107
|
-
action:
|
|
15108
|
-
project:
|
|
15109
|
-
assetId:
|
|
15110
|
-
styleId:
|
|
15324
|
+
import_zod8.z.object({
|
|
15325
|
+
action: import_zod8.z.literal("set-source"),
|
|
15326
|
+
project: import_zod8.z.string().min(1).optional(),
|
|
15327
|
+
assetId: import_zod8.z.string().min(1),
|
|
15328
|
+
styleId: import_zod8.z.string().min(1),
|
|
15111
15329
|
/** Manifest-relative path of the art that stands in for this asset in this style. */
|
|
15112
|
-
source:
|
|
15330
|
+
source: import_zod8.z.string().min(1),
|
|
15113
15331
|
expectedSha256: HexSha
|
|
15114
15332
|
}).strict(),
|
|
15115
|
-
|
|
15116
|
-
action:
|
|
15117
|
-
project:
|
|
15118
|
-
assetId:
|
|
15119
|
-
styleId:
|
|
15333
|
+
import_zod8.z.object({
|
|
15334
|
+
action: import_zod8.z.literal("clear-source"),
|
|
15335
|
+
project: import_zod8.z.string().min(1).optional(),
|
|
15336
|
+
assetId: import_zod8.z.string().min(1),
|
|
15337
|
+
styleId: import_zod8.z.string().min(1),
|
|
15120
15338
|
expectedSha256: HexSha
|
|
15121
15339
|
}).strict(),
|
|
15122
|
-
|
|
15123
|
-
action:
|
|
15124
|
-
project:
|
|
15125
|
-
styleId:
|
|
15340
|
+
import_zod8.z.object({
|
|
15341
|
+
action: import_zod8.z.literal("patch-style"),
|
|
15342
|
+
project: import_zod8.z.string().min(1).optional(),
|
|
15343
|
+
styleId: import_zod8.z.string().min(1),
|
|
15126
15344
|
expectedSha256: HexSha,
|
|
15127
|
-
patch:
|
|
15345
|
+
patch: import_zod8.z.object({
|
|
15128
15346
|
/** Candidates per generation, written to the provider's own option. */
|
|
15129
|
-
candidates:
|
|
15347
|
+
candidates: import_zod8.z.number().int().min(1).max(64).optional(),
|
|
15130
15348
|
/** Empty clears the style's own value (inherit, or the default). */
|
|
15131
|
-
promptPrefix:
|
|
15132
|
-
promptSuffix:
|
|
15349
|
+
promptPrefix: import_zod8.z.string().optional(),
|
|
15350
|
+
promptSuffix: import_zod8.z.string().optional(),
|
|
15133
15351
|
/** `#rrggbb` values; null or empty clears the style's own palette. */
|
|
15134
|
-
palette:
|
|
15352
|
+
palette: import_zod8.z.array(import_zod8.z.string().regex(/^#?[0-9a-f]{6}$/i, "expected a six-digit hex colour")).max(256).nullable().optional(),
|
|
15135
15353
|
/** Snap downloaded art to the palette; false clears the style's own value. */
|
|
15136
|
-
enforcePalette:
|
|
15354
|
+
enforcePalette: import_zod8.z.boolean().optional(),
|
|
15137
15355
|
/** Provider view name (PixelLab: low top-down, high top-down, side); empty clears. */
|
|
15138
|
-
view:
|
|
15356
|
+
view: import_zod8.z.string().max(64).nullable().optional(),
|
|
15139
15357
|
/** pixflux only; null clears the style's own value. */
|
|
15140
|
-
noBackground:
|
|
15358
|
+
noBackground: import_zod8.z.boolean().nullable().optional()
|
|
15141
15359
|
}).strict().refine((patch) => Object.keys(patch).length > 0, { message: "nothing to change" })
|
|
15142
15360
|
}).strict()
|
|
15143
15361
|
]);
|
|
@@ -15331,7 +15549,7 @@ async function applyManifestEdit(manifestPath, edit) {
|
|
|
15331
15549
|
var import_node_fs24 = require("fs");
|
|
15332
15550
|
var import_promises21 = require("fs/promises");
|
|
15333
15551
|
var import_node_path28 = __toESM(require("path"), 1);
|
|
15334
|
-
var
|
|
15552
|
+
var import_zod9 = require("zod");
|
|
15335
15553
|
var HAND_EDIT_DIR = "edits";
|
|
15336
15554
|
function handEditPath(loaded, spec) {
|
|
15337
15555
|
const style = loaded.manifest.styles[spec.styleId];
|
|
@@ -15428,35 +15646,35 @@ async function detachHandEdit(loaded, spec, opts = {}) {
|
|
|
15428
15646
|
});
|
|
15429
15647
|
return { manifestSha256: result.sha256, changed: result.changed };
|
|
15430
15648
|
}
|
|
15431
|
-
var CompanionOutputSchema =
|
|
15649
|
+
var CompanionOutputSchema = import_zod9.z.object({
|
|
15432
15650
|
/** Output role for a set member; null for a single image. */
|
|
15433
|
-
role:
|
|
15651
|
+
role: import_zod9.z.string().nullable(),
|
|
15434
15652
|
/** sha256 of the generated file this member started from; null when it started from untracked art. */
|
|
15435
|
-
basedOn:
|
|
15653
|
+
basedOn: import_zod9.z.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
15436
15654
|
/** sha256 of the member as saved, so a later change by another tool is visible. */
|
|
15437
|
-
sha256:
|
|
15655
|
+
sha256: import_zod9.z.string().regex(/^[0-9a-f]{64}$/)
|
|
15438
15656
|
}).strict();
|
|
15439
|
-
var CompanionV2Schema =
|
|
15440
|
-
version:
|
|
15657
|
+
var CompanionV2Schema = import_zod9.z.object({
|
|
15658
|
+
version: import_zod9.z.literal(2),
|
|
15441
15659
|
/** Editor identity the bridge reported, e.g. `pixelorama@v1.2.2-stable`. */
|
|
15442
|
-
editor:
|
|
15443
|
-
protocol:
|
|
15444
|
-
savedAt:
|
|
15660
|
+
editor: import_zod9.z.string().min(1),
|
|
15661
|
+
protocol: import_zod9.z.number().int().positive(),
|
|
15662
|
+
savedAt: import_zod9.z.string().datetime(),
|
|
15445
15663
|
/** Basename of the layered project file beside the edit, when one was kept. */
|
|
15446
|
-
project:
|
|
15664
|
+
project: import_zod9.z.string().min(1).nullable(),
|
|
15447
15665
|
/** One entry per file, in output order. */
|
|
15448
|
-
outputs:
|
|
15666
|
+
outputs: import_zod9.z.array(CompanionOutputSchema).min(1)
|
|
15449
15667
|
}).strict();
|
|
15450
|
-
var CompanionV1Schema =
|
|
15451
|
-
version:
|
|
15452
|
-
basedOn:
|
|
15453
|
-
sha256:
|
|
15454
|
-
editor:
|
|
15455
|
-
protocol:
|
|
15456
|
-
savedAt:
|
|
15457
|
-
project:
|
|
15668
|
+
var CompanionV1Schema = import_zod9.z.object({
|
|
15669
|
+
version: import_zod9.z.literal(1),
|
|
15670
|
+
basedOn: import_zod9.z.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
15671
|
+
sha256: import_zod9.z.string().regex(/^[0-9a-f]{64}$/),
|
|
15672
|
+
editor: import_zod9.z.string().min(1),
|
|
15673
|
+
protocol: import_zod9.z.number().int().positive(),
|
|
15674
|
+
savedAt: import_zod9.z.string().datetime(),
|
|
15675
|
+
project: import_zod9.z.string().min(1).nullable()
|
|
15458
15676
|
}).strict();
|
|
15459
|
-
var HandEditCompanionSchema =
|
|
15677
|
+
var HandEditCompanionSchema = import_zod9.z.union([CompanionV2Schema, CompanionV1Schema]).transform(
|
|
15460
15678
|
(value) => value.version === 2 ? value : {
|
|
15461
15679
|
version: 2,
|
|
15462
15680
|
editor: value.editor,
|
|
@@ -15576,40 +15794,40 @@ function openInEditor(file, editor = process.env.PIXELKILN_EDITOR) {
|
|
|
15576
15794
|
}
|
|
15577
15795
|
|
|
15578
15796
|
// src/gallery/edit.ts
|
|
15579
|
-
var Base64 =
|
|
15580
|
-
var HandEditRequestSchema =
|
|
15581
|
-
|
|
15582
|
-
action:
|
|
15583
|
-
project:
|
|
15584
|
-
assetId:
|
|
15585
|
-
styleId:
|
|
15586
|
-
expectedSha256:
|
|
15797
|
+
var Base64 = import_zod10.z.string().regex(/^[A-Za-z0-9+/]*={0,2}$/).max(Math.ceil(MAX_HAND_EDIT_BYTES / 3) * 4);
|
|
15798
|
+
var HandEditRequestSchema = import_zod10.z.discriminatedUnion("action", [
|
|
15799
|
+
import_zod10.z.object({
|
|
15800
|
+
action: import_zod10.z.literal("start-edit"),
|
|
15801
|
+
project: import_zod10.z.string().min(1).optional(),
|
|
15802
|
+
assetId: import_zod10.z.string().min(1),
|
|
15803
|
+
styleId: import_zod10.z.string().min(1),
|
|
15804
|
+
expectedSha256: import_zod10.z.string().regex(/^[0-9a-f]{64}$/),
|
|
15587
15805
|
/** Also launch the author's editor on the file. */
|
|
15588
|
-
open:
|
|
15806
|
+
open: import_zod10.z.boolean().optional()
|
|
15589
15807
|
}).strict(),
|
|
15590
|
-
|
|
15591
|
-
action:
|
|
15592
|
-
project:
|
|
15593
|
-
assetId:
|
|
15594
|
-
styleId:
|
|
15595
|
-
expectedSha256:
|
|
15808
|
+
import_zod10.z.object({
|
|
15809
|
+
action: import_zod10.z.literal("detach-edit"),
|
|
15810
|
+
project: import_zod10.z.string().min(1).optional(),
|
|
15811
|
+
assetId: import_zod10.z.string().min(1),
|
|
15812
|
+
styleId: import_zod10.z.string().min(1),
|
|
15813
|
+
expectedSha256: import_zod10.z.string().regex(/^[0-9a-f]{64}$/)
|
|
15596
15814
|
}).strict(),
|
|
15597
15815
|
/** From the in-browser editor: the page holds the bytes, the server validates and writes. */
|
|
15598
|
-
|
|
15599
|
-
action:
|
|
15600
|
-
project:
|
|
15601
|
-
assetId:
|
|
15602
|
-
styleId:
|
|
15603
|
-
expectedSha256:
|
|
15816
|
+
import_zod10.z.object({
|
|
15817
|
+
action: import_zod10.z.literal("save-edit"),
|
|
15818
|
+
project: import_zod10.z.string().min(1).optional(),
|
|
15819
|
+
assetId: import_zod10.z.string().min(1),
|
|
15820
|
+
styleId: import_zod10.z.string().min(1),
|
|
15821
|
+
expectedSha256: import_zod10.z.string().regex(/^[0-9a-f]{64}$/),
|
|
15604
15822
|
/** The flattened image; for a frame set, `frames` instead. */
|
|
15605
15823
|
png: Base64.min(1).optional(),
|
|
15606
15824
|
/** Every frame of a set, tagged with the role it was opened under (null for one added in the editor). */
|
|
15607
|
-
frames:
|
|
15825
|
+
frames: import_zod10.z.array(import_zod10.z.object({ role: import_zod10.z.string().min(1).nullable(), png: Base64.min(1) }).strict()).min(1).max(256).optional(),
|
|
15608
15826
|
/** The editor's layered project file, kept beside the edit. */
|
|
15609
15827
|
pxo: Base64.optional(),
|
|
15610
15828
|
/** Editor identity from the bridge's ready message. */
|
|
15611
|
-
editor:
|
|
15612
|
-
protocol:
|
|
15829
|
+
editor: import_zod10.z.string().min(1).max(200),
|
|
15830
|
+
protocol: import_zod10.z.number().int().positive()
|
|
15613
15831
|
}).strict()
|
|
15614
15832
|
]);
|
|
15615
15833
|
function createGalleryEditHandler(opts) {
|
|
@@ -16943,27 +17161,27 @@ async function serveGallery(opts) {
|
|
|
16943
17161
|
|
|
16944
17162
|
// src/gallery/generate.ts
|
|
16945
17163
|
var import_node_crypto9 = require("crypto");
|
|
16946
|
-
var
|
|
16947
|
-
var GenerateRequestSchema =
|
|
16948
|
-
project:
|
|
16949
|
-
keys:
|
|
17164
|
+
var import_zod11 = require("zod");
|
|
17165
|
+
var GenerateRequestSchema = import_zod11.z.object({
|
|
17166
|
+
project: import_zod11.z.string().min(1).optional(),
|
|
17167
|
+
keys: import_zod11.z.array(import_zod11.z.string().min(1)).min(1).max(500),
|
|
16950
17168
|
/**
|
|
16951
17169
|
* Regenerate work that is up to date, as `gen --force` does, and let the
|
|
16952
17170
|
* fetch replace a locally modified or untracked file. With `restore`, put
|
|
16953
17171
|
* the recorded bytes back over a modified file.
|
|
16954
17172
|
*/
|
|
16955
|
-
force:
|
|
17173
|
+
force: import_zod11.z.boolean().optional(),
|
|
16956
17174
|
/** Advance in-flight, review, or selected work without submitting anything. */
|
|
16957
|
-
resume:
|
|
17175
|
+
resume: import_zod11.z.boolean().optional(),
|
|
16958
17176
|
/** Re-download downloaded outputs and replace files whose object changed upstream. */
|
|
16959
|
-
refresh:
|
|
17177
|
+
refresh: import_zod11.z.boolean().optional(),
|
|
16960
17178
|
/** Put recorded outputs back on disk from the cache or the provider, without generating. */
|
|
16961
|
-
restore:
|
|
17179
|
+
restore: import_zod11.z.boolean().optional(),
|
|
16962
17180
|
/**
|
|
16963
17181
|
* Bring a replaced generation back: 1-based position in the record's
|
|
16964
17182
|
* history (newest first) or an output hash prefix. One key at a time.
|
|
16965
17183
|
*/
|
|
16966
|
-
revert:
|
|
17184
|
+
revert: import_zod11.z.string().min(1).max(64).optional()
|
|
16967
17185
|
}).strict().refine((request) => [request.resume, request.refresh, request.restore, request.revert !== void 0].filter(Boolean).length <= 1, {
|
|
16968
17186
|
message: "resume, refresh, restore, and revert are exclusive"
|
|
16969
17187
|
}).refine((request) => request.revert === void 0 || request.keys.length === 1, { message: "revert takes one key" });
|