pixelkiln 0.65.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 +932 -485
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +861 -451
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +859 -291
- package/dist/index.d.ts +859 -291
- package/dist/index.js +861 -451
- package/dist/index.js.map +1 -1
- package/docs/CHARACTERS.md +10 -0
- package/docs/CLI.md +17 -0
- package/docs/GENERATORS.md +44 -0
- package/docs/MANIFEST.md +9 -5
- package/docs/PIXELLAB.md +15 -14
- package/docs/REVISIONS.md +111 -10
- package/package.json +1 -1
- package/schema/manifest.schema.json +23 -2
- package/schema/recipe.schema.json +2 -1
- package/skills/pixelkiln/references/pixellab-roadmap.md +47 -21
- package/skills/pixelkiln/references/pixellab.md +45 -20
package/dist/index.cjs
CHANGED
|
@@ -322,7 +322,7 @@ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
|
322
322
|
// src/types.ts
|
|
323
323
|
var import_zod = require("zod");
|
|
324
324
|
var MediaTypeSchema = import_zod.z.enum(["image/png", "image/gif"]);
|
|
325
|
-
var GeneratorSchema = import_zod.z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro", "uiAsset", "uiElement"]);
|
|
325
|
+
var GeneratorSchema = import_zod.z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro", "uiAsset", "uiElement", "imageProFlash"]);
|
|
326
326
|
var GridConfidenceSchema = import_zod.z.enum(["low", "medium", "high"]);
|
|
327
327
|
var RevisionModeSchema = import_zod.z.enum([
|
|
328
328
|
"image-to-image",
|
|
@@ -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
|
]);
|
|
@@ -649,8 +650,46 @@ var RevisionSchema = import_zod.z.object({
|
|
|
649
650
|
/** `animate-pixminimax` only: facing direction, used only alongside `enhancePrompt` to hold the sprite's facing. */
|
|
650
651
|
direction: CharacterDirectionSchema.optional(),
|
|
651
652
|
/** `animate`/`animate-pixminimax` only: let PixelLab expand the action into a fuller motion description first. */
|
|
652
|
-
enhancePrompt: import_zod.z.boolean().optional()
|
|
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(),
|
|
678
|
+
/**
|
|
679
|
+
* `image-to-image`/`inpaint` only: which provider engine draws the
|
|
680
|
+
* edit. `pro-flash` selects PixelLab's Pro Flash edit and inpaint tier
|
|
681
|
+
* (`/edit-image-pro-flash`, `/inpaint-image-pro-flash`) instead of the
|
|
682
|
+
* default Pro endpoints; omit it for the default.
|
|
683
|
+
*/
|
|
684
|
+
engine: import_zod.z.enum(["pro-flash"]).optional()
|
|
653
685
|
}).strict().superRefine((revision, context) => {
|
|
686
|
+
if (revision.engine !== void 0 && revision.mode !== "image-to-image" && revision.mode !== "inpaint") {
|
|
687
|
+
context.addIssue({
|
|
688
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
689
|
+
message: "engine applies to image-to-image and inpaint revisions only",
|
|
690
|
+
path: ["engine"]
|
|
691
|
+
});
|
|
692
|
+
}
|
|
654
693
|
if (revision.mode === "inpaint" && !revision.mask) {
|
|
655
694
|
context.addIssue({
|
|
656
695
|
code: import_zod.z.ZodIssueCode.custom,
|
|
@@ -726,18 +765,41 @@ var RevisionSchema = import_zod.z.object({
|
|
|
726
765
|
path: ["fps"]
|
|
727
766
|
});
|
|
728
767
|
}
|
|
729
|
-
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax") {
|
|
768
|
+
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax" && revision.mode !== "animate-skeleton") {
|
|
730
769
|
context.addIssue({
|
|
731
770
|
code: import_zod.z.ZodIssueCode.custom,
|
|
732
|
-
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",
|
|
733
779
|
path: ["direction"]
|
|
734
780
|
});
|
|
735
781
|
}
|
|
736
782
|
if (revision.frames !== void 0 && revision.frames % 2 !== 0) {
|
|
737
783
|
context.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: "frames must be even", path: ["frames"] });
|
|
738
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
|
+
}
|
|
739
801
|
});
|
|
740
|
-
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"];
|
|
741
803
|
var MEMBER_SET_REVISION_MODES = ["reduce-colors", "correct-pixelart", "edit-animation"];
|
|
742
804
|
var StyleObjectSchema = import_zod.z.object({
|
|
743
805
|
/** Generation backend for this style. Omit to inherit the manifest default. */
|
|
@@ -939,8 +1001,8 @@ var StyleObjectSchema = import_zod.z.object({
|
|
|
939
1001
|
/** `character` only. Body template: `mannequin` (default), a quadruped (`bear`, `cat`, `dog`, `horse`, `lion`), or `custom` for `pro-flash`. */
|
|
940
1002
|
template: import_zod.z.string().min(1).optional(),
|
|
941
1003
|
/**
|
|
942
|
-
* `character`
|
|
943
|
-
* the style image lends. Each defaults to true.
|
|
1004
|
+
* `character` `pro-flash` bases and `imageProFlash` styles, with a
|
|
1005
|
+
* style image: which traits the style image lends. Each defaults to true.
|
|
944
1006
|
*/
|
|
945
1007
|
styleTraits: import_zod.z.object({
|
|
946
1008
|
palette: import_zod.z.boolean().optional(),
|
|
@@ -1369,11 +1431,17 @@ var LockEntrySchema = import_zod.z.object({
|
|
|
1369
1431
|
paletteImageSha256: import_zod.z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1370
1432
|
dithering: RevisionDitheringSchema.optional(),
|
|
1371
1433
|
ditheringStrength: import_zod.z.number().min(0).max(10).optional(),
|
|
1372
|
-
|
|
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(),
|
|
1373
1437
|
fps: import_zod.z.number().int().min(1).max(60).optional(),
|
|
1374
1438
|
lastFrameSha256: import_zod.z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1375
1439
|
direction: CharacterDirectionSchema.optional(),
|
|
1376
|
-
enhancePrompt: import_zod.z.boolean().optional()
|
|
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(),
|
|
1444
|
+
engine: import_zod.z.enum(["pro-flash"]).optional()
|
|
1377
1445
|
}).strict().nullable().default(null),
|
|
1378
1446
|
/** For a mirror: the asset it flips and a hash over that asset's output hashes when this was made. */
|
|
1379
1447
|
mirror: import_zod.z.object({
|
|
@@ -1559,7 +1627,7 @@ function exitCodeFor(err) {
|
|
|
1559
1627
|
}
|
|
1560
1628
|
|
|
1561
1629
|
// src/client.ts
|
|
1562
|
-
var
|
|
1630
|
+
var import_zod3 = require("zod");
|
|
1563
1631
|
|
|
1564
1632
|
// src/http.ts
|
|
1565
1633
|
var MAX_RETRIES = 4;
|
|
@@ -1609,254 +1677,289 @@ function fetchWithRetry(request, opts = {}) {
|
|
|
1609
1677
|
};
|
|
1610
1678
|
}
|
|
1611
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
|
+
|
|
1612
1703
|
// src/client.ts
|
|
1613
1704
|
var BASE = process.env.PIXELLAB_API_BASE ?? "https://api.pixellab.ai/v2";
|
|
1614
1705
|
var MAX_DOWNLOAD_BYTES = 64 * 1024 * 1024;
|
|
1615
|
-
var BalanceResponseSchema =
|
|
1616
|
-
credits:
|
|
1617
|
-
subscription:
|
|
1618
|
-
generations:
|
|
1619
|
-
total:
|
|
1620
|
-
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()
|
|
1621
1712
|
}).passthrough()
|
|
1622
1713
|
}).passthrough();
|
|
1623
|
-
var ObjectSubmitSchema =
|
|
1624
|
-
background_job_id:
|
|
1625
|
-
object_id:
|
|
1626
|
-
status:
|
|
1627
|
-
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)
|
|
1628
1719
|
}).passthrough();
|
|
1629
|
-
var MapSubmitSchema =
|
|
1630
|
-
background_job_id:
|
|
1631
|
-
object_id:
|
|
1632
|
-
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")
|
|
1633
1724
|
}).passthrough();
|
|
1634
|
-
var UsageSchema =
|
|
1635
|
-
type:
|
|
1636
|
-
usd:
|
|
1637
|
-
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()
|
|
1638
1729
|
}).passthrough().nullable().optional();
|
|
1639
|
-
var TilesSubmitSchema =
|
|
1640
|
-
tile_id:
|
|
1641
|
-
background_job_id:
|
|
1642
|
-
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")
|
|
1643
1734
|
}).passthrough();
|
|
1644
|
-
var TilesProSchema =
|
|
1645
|
-
storage_urls:
|
|
1646
|
-
kind:
|
|
1647
|
-
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()
|
|
1648
1739
|
}).passthrough();
|
|
1649
|
-
var TilesetSubmitSchema =
|
|
1650
|
-
tileset_id:
|
|
1651
|
-
background_job_id:
|
|
1652
|
-
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")
|
|
1653
1744
|
}).passthrough();
|
|
1654
|
-
var TilesetTileSchema =
|
|
1655
|
-
id:
|
|
1656
|
-
name:
|
|
1657
|
-
image:
|
|
1658
|
-
corners:
|
|
1659
|
-
pattern_4x4:
|
|
1660
|
-
row_0:
|
|
1661
|
-
row_1:
|
|
1662
|
-
row_2:
|
|
1663
|
-
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())
|
|
1664
1755
|
}).passthrough()
|
|
1665
1756
|
}).passthrough();
|
|
1666
|
-
var TilesetGetSchema =
|
|
1667
|
-
tileset:
|
|
1668
|
-
total_tiles:
|
|
1669
|
-
tile_size:
|
|
1670
|
-
terrain_types:
|
|
1671
|
-
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)
|
|
1672
1763
|
}).passthrough(),
|
|
1673
1764
|
usage: UsageSchema
|
|
1674
1765
|
}).passthrough();
|
|
1675
|
-
var IsometricTileSubmitSchema =
|
|
1676
|
-
tile_id:
|
|
1677
|
-
background_job_id:
|
|
1678
|
-
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")
|
|
1679
1770
|
}).passthrough();
|
|
1680
|
-
var IsometricTileGetSchema =
|
|
1681
|
-
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(),
|
|
1682
1773
|
usage: UsageSchema
|
|
1683
1774
|
}).passthrough();
|
|
1684
|
-
var UiAssetSubmitSchema =
|
|
1685
|
-
ui_asset_id:
|
|
1686
|
-
background_job_id:
|
|
1687
|
-
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"),
|
|
1688
1779
|
usage: UsageSchema
|
|
1689
1780
|
}).passthrough();
|
|
1690
|
-
var UiAssetGetSchema =
|
|
1691
|
-
id:
|
|
1692
|
-
status:
|
|
1693
|
-
image_url:
|
|
1694
|
-
progress_percent:
|
|
1695
|
-
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()
|
|
1696
1787
|
}).passthrough();
|
|
1697
|
-
var RevisionJobSubmitSchema =
|
|
1698
|
-
background_job_id:
|
|
1699
|
-
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")
|
|
1700
1791
|
}).passthrough();
|
|
1701
|
-
var ObjectAnimationGroupSchema =
|
|
1702
|
-
animation_group_id:
|
|
1703
|
-
display_name:
|
|
1704
|
-
description:
|
|
1705
|
-
frame_count:
|
|
1706
|
-
directions:
|
|
1707
|
-
|
|
1708
|
-
direction:
|
|
1709
|
-
storage_urls:
|
|
1710
|
-
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()
|
|
1711
1802
|
}).passthrough()
|
|
1712
1803
|
).default([])
|
|
1713
1804
|
}).passthrough();
|
|
1714
|
-
var PixelLabObjectSchema =
|
|
1715
|
-
id:
|
|
1716
|
-
name:
|
|
1717
|
-
state_name:
|
|
1718
|
-
prompt:
|
|
1719
|
-
size:
|
|
1720
|
-
directions:
|
|
1721
|
-
created_at:
|
|
1722
|
-
view:
|
|
1723
|
-
preview_url:
|
|
1724
|
-
rotation_urls:
|
|
1725
|
-
frame_urls:
|
|
1726
|
-
tags:
|
|
1727
|
-
status:
|
|
1728
|
-
progress_percent:
|
|
1729
|
-
eta_seconds:
|
|
1730
|
-
group_id:
|
|
1731
|
-
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)
|
|
1831
|
+
}).passthrough();
|
|
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()
|
|
1732
1839
|
}).passthrough();
|
|
1733
|
-
var
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
description: import_zod2.z.string().nullable().default(null),
|
|
1737
|
-
width: import_zod2.z.number().nullable().default(null),
|
|
1738
|
-
height: import_zod2.z.number().nullable().default(null),
|
|
1739
|
-
download_url: import_zod2.z.string().nullable().default(null)
|
|
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()
|
|
1740
1843
|
}).passthrough();
|
|
1741
|
-
var
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
usage:
|
|
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()
|
|
1748
1851
|
}).passthrough();
|
|
1749
|
-
var
|
|
1750
|
-
|
|
1751
|
-
|
|
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()
|
|
1752
1858
|
}).passthrough();
|
|
1753
|
-
var
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
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()
|
|
1759
1866
|
}).passthrough();
|
|
1760
|
-
var
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
download_atlas_url: import_zod2.z.string().nullable().optional(),
|
|
1765
|
-
download_ttf_url: import_zod2.z.string().nullable().optional(),
|
|
1766
|
-
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()
|
|
1767
1871
|
}).passthrough();
|
|
1768
|
-
var
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
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"),
|
|
1773
1876
|
usage: UsageSchema
|
|
1774
1877
|
}).passthrough();
|
|
1775
|
-
var AnimateSubmitSchema =
|
|
1776
|
-
background_job_ids:
|
|
1777
|
-
directions:
|
|
1778
|
-
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"),
|
|
1779
1882
|
usage: UsageSchema
|
|
1780
1883
|
}).passthrough();
|
|
1781
|
-
var ObjectProSubmitSchema =
|
|
1782
|
-
object_id:
|
|
1783
|
-
background_job_id:
|
|
1784
|
-
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"),
|
|
1785
1888
|
usage: UsageSchema
|
|
1786
1889
|
}).passthrough();
|
|
1787
|
-
var DirectionSubmissionSchema =
|
|
1788
|
-
direction:
|
|
1789
|
-
status:
|
|
1790
|
-
background_job_id:
|
|
1791
|
-
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)
|
|
1792
1895
|
}).passthrough();
|
|
1793
|
-
var AnimateObjectSubmitSchema =
|
|
1794
|
-
animation_group_id:
|
|
1795
|
-
object_id:
|
|
1796
|
-
mode:
|
|
1797
|
-
frame_count:
|
|
1798
|
-
display_name:
|
|
1799
|
-
description:
|
|
1800
|
-
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),
|
|
1801
1904
|
usage: UsageSchema
|
|
1802
1905
|
}).passthrough();
|
|
1803
|
-
var PortraitSubmitSchema =
|
|
1804
|
-
background_job_id:
|
|
1805
|
-
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"),
|
|
1806
1909
|
usage: UsageSchema
|
|
1807
1910
|
}).passthrough();
|
|
1808
|
-
var PortraitJobSchema =
|
|
1809
|
-
status:
|
|
1810
|
-
download_url:
|
|
1811
|
-
width:
|
|
1812
|
-
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()
|
|
1813
1916
|
}).passthrough();
|
|
1814
|
-
var SetPortraitSchema =
|
|
1815
|
-
character_id:
|
|
1816
|
-
size:
|
|
1817
|
-
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),
|
|
1818
1921
|
usage: UsageSchema
|
|
1819
1922
|
}).passthrough();
|
|
1820
|
-
var TransferOutfitSubmitSchema =
|
|
1821
|
-
background_job_id:
|
|
1822
|
-
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"),
|
|
1823
1926
|
usage: UsageSchema
|
|
1824
1927
|
}).passthrough();
|
|
1825
|
-
var CharacterAnimationDirectionSchema =
|
|
1826
|
-
direction:
|
|
1827
|
-
frame_count:
|
|
1828
|
-
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())
|
|
1829
1932
|
}).passthrough();
|
|
1830
|
-
var CharacterAnimationSchema2 =
|
|
1831
|
-
animation_type:
|
|
1832
|
-
display_name:
|
|
1833
|
-
animation_group_id:
|
|
1834
|
-
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)
|
|
1835
1938
|
}).passthrough();
|
|
1836
|
-
var CharacterSchema =
|
|
1837
|
-
id:
|
|
1838
|
-
name:
|
|
1839
|
-
state_name:
|
|
1840
|
-
prompt:
|
|
1841
|
-
size:
|
|
1842
|
-
directions:
|
|
1843
|
-
created_at:
|
|
1844
|
-
updated_at:
|
|
1845
|
-
animation_count:
|
|
1846
|
-
template_id:
|
|
1847
|
-
view:
|
|
1848
|
-
status:
|
|
1849
|
-
rotation_urls:
|
|
1850
|
-
tags:
|
|
1851
|
-
group_id:
|
|
1852
|
-
animations:
|
|
1853
|
-
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()
|
|
1854
1957
|
}).passthrough();
|
|
1855
|
-
var CharacterListSchema =
|
|
1856
|
-
var BackgroundJobSchema =
|
|
1857
|
-
id:
|
|
1858
|
-
status:
|
|
1859
|
-
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(),
|
|
1860
1963
|
/**
|
|
1861
1964
|
* The billed amount, confirmed live for a `map` object and a standard
|
|
1862
1965
|
* character base (docs/ENDPOINTS.md, "Limits and billing"); duplicated at
|
|
@@ -1864,7 +1967,7 @@ var BackgroundJobSchema = import_zod2.z.object({
|
|
|
1864
1967
|
*/
|
|
1865
1968
|
usage: UsageSchema
|
|
1866
1969
|
}).passthrough();
|
|
1867
|
-
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();
|
|
1868
1971
|
function validateResponse(schema, raw, operation) {
|
|
1869
1972
|
const parsed = schema.safeParse(raw);
|
|
1870
1973
|
if (parsed.success) return parsed.data;
|
|
@@ -2190,7 +2293,7 @@ var PixelLabClient = class {
|
|
|
2190
2293
|
const body = {
|
|
2191
2294
|
description: args.description,
|
|
2192
2295
|
n_directions: args.directions,
|
|
2193
|
-
...args.reference ? { first_frame: encode(args.reference) } : { image_size: { width: args.size, height: args.size } },
|
|
2296
|
+
...args.sourceImageId ? { source_image_id: args.sourceImageId } : args.reference ? { first_frame: encode(args.reference) } : { image_size: { width: args.size, height: args.size } },
|
|
2194
2297
|
...args.view ? { view: args.view } : {},
|
|
2195
2298
|
...args.seed != null ? { seed: args.seed } : {},
|
|
2196
2299
|
...args.styleReference && args.styleReferenceSize ? {
|
|
@@ -2337,8 +2440,9 @@ var PixelLabClient = class {
|
|
|
2337
2440
|
description: args.description,
|
|
2338
2441
|
template_id: args.template,
|
|
2339
2442
|
n_directions: 8,
|
|
2340
|
-
// The author's sprite sets the canvas; a size only applies to text
|
|
2341
|
-
|
|
2443
|
+
// The author's sprite sets the canvas; a size only applies to text
|
|
2444
|
+
// creation. An owned copy of the same sprite is referenced by id.
|
|
2445
|
+
...args.sourceImageId ? { source_image_id: args.sourceImageId } : south ? { first_frame: encode(south) } : { image_size: imageSize },
|
|
2342
2446
|
...args.view ? { view: args.view } : {},
|
|
2343
2447
|
...args.seed != null ? { seed: args.seed } : {},
|
|
2344
2448
|
...args.styleReference && args.styleReferenceSize ? {
|
|
@@ -2610,6 +2714,66 @@ var PixelLabClient = class {
|
|
|
2610
2714
|
"generate-image-v2"
|
|
2611
2715
|
);
|
|
2612
2716
|
}
|
|
2717
|
+
/**
|
|
2718
|
+
* `/create-image-pro-flash`: one native pixel-art image from a
|
|
2719
|
+
* description, optionally styled after a style image with per-trait
|
|
2720
|
+
* toggles, on the same Pro Flash model `character`/`objectPro` use for
|
|
2721
|
+
* their `pro-flash` engine. Sizes run 16 to 256 per side in multiples of 4.
|
|
2722
|
+
* A plain background job; `pollRevision`'s generic reader takes the
|
|
2723
|
+
* finished image. The response's `source_image_id` is what a Pro Flash
|
|
2724
|
+
* character or object can reuse instead of an upload.
|
|
2725
|
+
*/
|
|
2726
|
+
async createImageProFlash(args) {
|
|
2727
|
+
const body = {
|
|
2728
|
+
description: args.description,
|
|
2729
|
+
image_size: { width: args.width, height: args.height }
|
|
2730
|
+
};
|
|
2731
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
2732
|
+
if (args.seed != null) body.seed = args.seed;
|
|
2733
|
+
if (args.styleImage) {
|
|
2734
|
+
body.style_image = { image: args.styleImage.image, size: { width: args.styleImage.width, height: args.styleImage.height } };
|
|
2735
|
+
const traits = args.styleTraits;
|
|
2736
|
+
if (traits) {
|
|
2737
|
+
body.style_options = {
|
|
2738
|
+
...traits.palette !== void 0 ? { color_palette: traits.palette } : {},
|
|
2739
|
+
...traits.outline !== void 0 ? { outline: traits.outline } : {},
|
|
2740
|
+
...traits.detail !== void 0 ? { detail: traits.detail } : {},
|
|
2741
|
+
...traits.shading !== void 0 ? { shading: traits.shading } : {}
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
return validateResponse(
|
|
2746
|
+
ProFlashImageSubmitSchema,
|
|
2747
|
+
await this.request("/create-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
2748
|
+
"create-image-pro-flash"
|
|
2749
|
+
);
|
|
2750
|
+
}
|
|
2751
|
+
/** `/edit-image-pro-flash`, text method: edit one image at its own size. The canvas never grows or resizes. */
|
|
2752
|
+
async editImageProFlash(args) {
|
|
2753
|
+
const body = { image: args.image, method: "text", description: args.description };
|
|
2754
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
2755
|
+
if (args.seed != null) body.seed = args.seed;
|
|
2756
|
+
return validateResponse(
|
|
2757
|
+
ProFlashImageSubmitSchema,
|
|
2758
|
+
await this.request("/edit-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
2759
|
+
"edit-image-pro-flash"
|
|
2760
|
+
);
|
|
2761
|
+
}
|
|
2762
|
+
/**
|
|
2763
|
+
* `/inpaint-image-pro-flash`: replace only the white pixels of a same-size
|
|
2764
|
+
* black/white mask, keeping everything else exactly. `Modify current
|
|
2765
|
+
* layer` (the endpoint's default) returns the full composite.
|
|
2766
|
+
*/
|
|
2767
|
+
async inpaintImageProFlash(args) {
|
|
2768
|
+
const body = { image: args.image, mask_image: args.maskImage, description: args.description };
|
|
2769
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
2770
|
+
if (args.seed != null) body.seed = args.seed;
|
|
2771
|
+
return validateResponse(
|
|
2772
|
+
ProFlashImageSubmitSchema,
|
|
2773
|
+
await this.request("/inpaint-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
2774
|
+
"inpaint-image-pro-flash"
|
|
2775
|
+
);
|
|
2776
|
+
}
|
|
2613
2777
|
/**
|
|
2614
2778
|
* `/generate-ui-v2` ("Generate UI (Pro)"): one UI element (a button, a
|
|
2615
2779
|
* health bar, an inventory slot, a dialogue box) from a description,
|
|
@@ -2834,6 +2998,61 @@ var PixelLabClient = class {
|
|
|
2834
2998
|
"animate-pixminimax"
|
|
2835
2999
|
);
|
|
2836
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
|
+
}
|
|
2837
3056
|
async getBackgroundJob(jobId) {
|
|
2838
3057
|
const raw = await this.request(`/background-jobs/${encodeURIComponent(jobId)}`);
|
|
2839
3058
|
return validateResponse(BackgroundJobSchema, raw, "background-jobs/{id}");
|
|
@@ -3490,6 +3709,7 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
3490
3709
|
uiPieces: spec.uiPieces,
|
|
3491
3710
|
uiElements: spec.uiElements,
|
|
3492
3711
|
uiColorPalette: spec.uiColorPalette,
|
|
3712
|
+
styleTraits: spec.styleTraits,
|
|
3493
3713
|
styleImages: styleImageHashes,
|
|
3494
3714
|
// A character family: the engine and rotations of a base, the parent's
|
|
3495
3715
|
// generated bytes for a state or animation (so a regenerated parent
|
|
@@ -3566,7 +3786,11 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
3566
3786
|
fps: spec.revision.fps,
|
|
3567
3787
|
lastFrameSha256: spec.revision.lastFrameSha256,
|
|
3568
3788
|
direction: spec.revision.direction,
|
|
3569
|
-
enhancePrompt: spec.revision.enhancePrompt
|
|
3789
|
+
enhancePrompt: spec.revision.enhancePrompt,
|
|
3790
|
+
keypointsSha256: spec.revision.keypointsSha256,
|
|
3791
|
+
skeletonTemplate: spec.revision.skeletonTemplate,
|
|
3792
|
+
description: spec.revision.description,
|
|
3793
|
+
engine: spec.revision.engine
|
|
3570
3794
|
} : void 0
|
|
3571
3795
|
})
|
|
3572
3796
|
);
|
|
@@ -3622,8 +3846,11 @@ function proFlashCharacterCost(width, height, fromReference) {
|
|
|
3622
3846
|
const side = Math.max(32, Math.ceil(Math.max(width, height) / 4) * 4);
|
|
3623
3847
|
const rotations = Math.max(1, Math.ceil(side * side * 8 / 65536));
|
|
3624
3848
|
if (fromReference) return rotations;
|
|
3625
|
-
|
|
3626
|
-
|
|
3849
|
+
return proFlashImageCost(side, side) + rotations;
|
|
3850
|
+
}
|
|
3851
|
+
function proFlashImageCost(width, height) {
|
|
3852
|
+
const side = Math.max(width, height);
|
|
3853
|
+
return side <= 96 ? 5 : side <= 208 ? 6 : 9;
|
|
3627
3854
|
}
|
|
3628
3855
|
function characterAnimationName(spec) {
|
|
3629
3856
|
return `pixelkiln:${spec.styleId}/${spec.assetId}`;
|
|
@@ -3651,6 +3878,18 @@ function objectProCost(spec) {
|
|
|
3651
3878
|
const south = object.reference;
|
|
3652
3879
|
return south ? proFlashObjectCost(south.width, south.height, object.directions, true) : proFlashObjectCost(spec.width, spec.height, object.directions, false);
|
|
3653
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
|
+
}
|
|
3654
3893
|
var CHARACTER_TEMPLATES = ["mannequin", "bear", "cat", "dog", "horse", "lion"];
|
|
3655
3894
|
var PRO_FLASH_TEMPLATES = [...CHARACTER_TEMPLATES, "custom"];
|
|
3656
3895
|
function encodeAnimationJob(job) {
|
|
@@ -3699,7 +3938,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3699
3938
|
return new _PixelLabProvider(new PixelLabClient("download-only"));
|
|
3700
3939
|
}
|
|
3701
3940
|
supports(generator) {
|
|
3702
|
-
return generator === "1dir" || generator === "map" || generator === "pixflux" || generator === "tiles" || generator === "terrain" || generator === "imagePro" || generator === "character" || generator === "isometricTile" || generator === "objectPro" || generator === "uiAsset" || generator === "uiElement";
|
|
3941
|
+
return generator === "1dir" || generator === "map" || generator === "pixflux" || generator === "tiles" || generator === "terrain" || generator === "imagePro" || generator === "character" || generator === "isometricTile" || generator === "objectPro" || generator === "uiAsset" || generator === "uiElement" || generator === "imageProFlash";
|
|
3703
3942
|
}
|
|
3704
3943
|
/**
|
|
3705
3944
|
* `inpaint` (`/inpaint-v3`, a mask) and `image-to-image` (`/edit-images-v2`,
|
|
@@ -3709,7 +3948,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3709
3948
|
* rather than a described edit — and `animate`/`animate-pixminimax`
|
|
3710
3949
|
* (`/animate-with-text-v3`, `/animate-pixminimax`), which animate any loose
|
|
3711
3950
|
* image from a text description with no character/object resource
|
|
3712
|
-
* 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
|
|
3713
3954
|
* from one keyframe to another) and `edit-animation`
|
|
3714
3955
|
* (`/edit-animation-v2`, one text edit applied across a whole frame set).
|
|
3715
3956
|
* `outpaint` does not: there is no canvas-expansion endpoint in the API,
|
|
@@ -3717,7 +3958,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3717
3958
|
* outpaint path yet.
|
|
3718
3959
|
*/
|
|
3719
3960
|
supportsRevision(mode2) {
|
|
3720
|
-
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";
|
|
3721
3962
|
}
|
|
3722
3963
|
/** PixelLab's own constraints: submissions must be >2s apart, and
|
|
3723
3964
|
* background jobs in flight are capped by subscription tier (Tier 1=8,
|
|
@@ -3748,6 +3989,10 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3748
3989
|
if (spec.revision?.mode === "reduce-colors" || spec.revision?.mode === "correct-pixelart") {
|
|
3749
3990
|
return { unit: "generations", amount: 0.1, candidates: 1 };
|
|
3750
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
|
+
}
|
|
3751
3996
|
if (spec.revision?.mode === "interpolate" || spec.revision?.mode === "edit-animation") {
|
|
3752
3997
|
const width = spec.revision.sourceWidth ?? spec.width;
|
|
3753
3998
|
const height = spec.revision.sourceHeight ?? spec.height;
|
|
@@ -3761,6 +4006,13 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3761
4006
|
const base = Math.max(1, Math.ceil(width * height * frames / 65536));
|
|
3762
4007
|
return { unit: "generations", amount: spec.revision.enhancePrompt ? base + 0.05 : base, candidates: 1 };
|
|
3763
4008
|
}
|
|
4009
|
+
if (spec.revision?.engine === "pro-flash") {
|
|
4010
|
+
return {
|
|
4011
|
+
unit: "generations",
|
|
4012
|
+
amount: proFlashImageCost(spec.revision.sourceWidth ?? spec.width, spec.revision.sourceHeight ?? spec.height),
|
|
4013
|
+
candidates: 1
|
|
4014
|
+
};
|
|
4015
|
+
}
|
|
3764
4016
|
if (spec.revision) {
|
|
3765
4017
|
const width = spec.revision.sourceWidth ?? spec.width;
|
|
3766
4018
|
const height = spec.revision.sourceHeight ?? spec.height;
|
|
@@ -3775,6 +4027,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3775
4027
|
if (spec.generator === "objectPro") {
|
|
3776
4028
|
return { unit: "generations", amount: objectProCost(spec), candidates: 1 };
|
|
3777
4029
|
}
|
|
4030
|
+
if (spec.generator === "imageProFlash") {
|
|
4031
|
+
return { unit: "generations", amount: proFlashImageCost(spec.width, spec.height), candidates: 1 };
|
|
4032
|
+
}
|
|
3778
4033
|
return {
|
|
3779
4034
|
unit: "generations",
|
|
3780
4035
|
amount: generationCost(spec.width, spec.height, spec.generator),
|
|
@@ -3788,7 +4043,17 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3788
4043
|
`PixelLab ${spec.revision.mode} reads one source image; ${spec.revision.sourceAssetId} is a ${members.length}-member set (${members[0].role}, ...). Revise one member through a declared source, or use reduce-colors, correct-pixelart, or edit-animation, which take the whole set`
|
|
3789
4044
|
);
|
|
3790
4045
|
}
|
|
3791
|
-
if (spec.revision?.
|
|
4046
|
+
if (spec.revision?.engine === "pro-flash") {
|
|
4047
|
+
const { sourceWidth: width, sourceHeight: height, mode: mode2 } = spec.revision;
|
|
4048
|
+
if (width != null && height != null && (width < 32 || height < 32 || width > 256 || height > 256 || width % 4 || height % 4)) {
|
|
4049
|
+
throw new Error(
|
|
4050
|
+
`PixelLab pro-flash ${mode2} source is ${width}x${height}; the API takes 32 to 256 pixels per side, in multiples of 4`
|
|
4051
|
+
);
|
|
4052
|
+
}
|
|
4053
|
+
if (spec.revision.strength != null) {
|
|
4054
|
+
throw new Error(`PixelLab pro-flash ${mode2} takes no strength; the edit applies in full`);
|
|
4055
|
+
}
|
|
4056
|
+
} else if (spec.revision?.mode === "inpaint") {
|
|
3792
4057
|
const { sourceWidth: width, sourceHeight: height } = spec.revision;
|
|
3793
4058
|
if (width != null && height != null && (width < 32 || height < 32 || width > 512 || height > 512)) {
|
|
3794
4059
|
throw new Error(`PixelLab inpaint source is ${width}x${height}; the API takes 32 to 512 pixels per side`);
|
|
@@ -3809,6 +4074,18 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3809
4074
|
throw new Error(`PixelLab correct-pixelart source is ${width}x${height}; the API takes at most 1024 pixels per side`);
|
|
3810
4075
|
}
|
|
3811
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
|
+
}
|
|
3812
4089
|
if (spec.revision?.mode === "animate" || spec.revision?.mode === "animate-pixminimax") {
|
|
3813
4090
|
const { sourceWidth: width, sourceHeight: height, mode: mode2, frames, lastFrameWidth, lastFrameHeight } = spec.revision;
|
|
3814
4091
|
if (width != null && height != null && (width > 256 || height > 256)) {
|
|
@@ -3869,6 +4146,19 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3869
4146
|
`PixelLab uiAsset is ${spec.width}x${spec.height}; the API takes 192 to 688 pixels per side (the exact ceiling also depends on aspect ratio \u2014 square tops out at 512, 16:9 at 688x384, 9:16 at 384x688, 4:3 at 600x448, 3:4 at 448x600)`
|
|
3870
4147
|
);
|
|
3871
4148
|
}
|
|
4149
|
+
if (spec.generator === "imageProFlash") {
|
|
4150
|
+
if (spec.width < 16 || spec.height < 16 || spec.width > 256 || spec.height > 256 || spec.width % 4 || spec.height % 4) {
|
|
4151
|
+
throw new Error(
|
|
4152
|
+
`PixelLab imageProFlash is ${spec.width}x${spec.height}; the API takes 16 to 256 pixels per side, in multiples of 4`
|
|
4153
|
+
);
|
|
4154
|
+
}
|
|
4155
|
+
if (styleImages.length > 1) {
|
|
4156
|
+
throw new Error("PixelLab imageProFlash takes one style image; list at most one styleImages entry");
|
|
4157
|
+
}
|
|
4158
|
+
if (spec.styleTraits && !styleImages.length) {
|
|
4159
|
+
throw new Error("PixelLab imageProFlash: styleTraits choose what a style image lends; add a styleImages entry or drop them");
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
3872
4162
|
if (spec.generator === "uiElement" && (spec.width < 16 || spec.height < 16 || spec.width > 792 || spec.height > 688)) {
|
|
3873
4163
|
throw new Error(
|
|
3874
4164
|
`PixelLab uiElement is ${spec.width}x${spec.height}; the API takes 16 to 792 wide and 16 to 688 tall (the exact ceiling depends on aspect ratio \u2014 square tops out at 512, 16:9 at 688x384)`
|
|
@@ -4222,7 +4512,8 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4222
4512
|
concept: character.concept ? readPose(spec, "concept image", character.concept) : void 0,
|
|
4223
4513
|
styleCharacterId: character.styleAnchor ? requireStyleObjectId(spec, context) : void 0,
|
|
4224
4514
|
styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
|
|
4225
|
-
styleTraits: character.styleTraits
|
|
4515
|
+
styleTraits: character.styleTraits,
|
|
4516
|
+
sourceImageId: character.mode === "pro-flash" ? context?.referenceSourceImageId : void 0
|
|
4226
4517
|
});
|
|
4227
4518
|
return { jobId: res2.character_id, metadata: { character: { kind: "base", characterId: res2.character_id, mode: character.mode, directions: character.directions, backgroundJobId: res2.background_job_id } } };
|
|
4228
4519
|
}
|
|
@@ -4357,7 +4648,8 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4357
4648
|
reference: object.reference ? readPose(spec, "reference sprite", object.reference) : void 0,
|
|
4358
4649
|
styleReference: styleImage ? { base64: styleImage.base64, format: styleImage.format } : void 0,
|
|
4359
4650
|
styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
|
|
4360
|
-
styleTraits: object.styleTraits
|
|
4651
|
+
styleTraits: object.styleTraits,
|
|
4652
|
+
sourceImageId: context?.referenceSourceImageId
|
|
4361
4653
|
});
|
|
4362
4654
|
return { jobId: res2.object_id, metadata: { objectPro: { kind: "base", objectId: res2.object_id, directions: object.directions, backgroundJobId: res2.background_job_id } } };
|
|
4363
4655
|
}
|
|
@@ -4656,6 +4948,19 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4656
4948
|
});
|
|
4657
4949
|
return { jobId: res2.ui_asset_id, metadata: { backgroundJobId: res2.background_job_id } };
|
|
4658
4950
|
}
|
|
4951
|
+
if (spec.generator === "imageProFlash") {
|
|
4952
|
+
const style = styleImages[0];
|
|
4953
|
+
const res2 = await this.client.createImageProFlash({
|
|
4954
|
+
description: spec.prompt,
|
|
4955
|
+
width: spec.width,
|
|
4956
|
+
height: spec.height,
|
|
4957
|
+
noBackground: spec.noBackground,
|
|
4958
|
+
seed: spec.seed,
|
|
4959
|
+
styleImage: style ? { image: { base64: style.base64, format: style.format }, width: style.width, height: style.height } : void 0,
|
|
4960
|
+
styleTraits: spec.styleTraits
|
|
4961
|
+
});
|
|
4962
|
+
return { jobId: res2.background_job_id, metadata: { imageProFlash: proFlashRecord(res2) } };
|
|
4963
|
+
}
|
|
4659
4964
|
if (spec.generator === "uiElement") {
|
|
4660
4965
|
const concept = styleImages[0];
|
|
4661
4966
|
const res2 = await this.client.generateUiV2({
|
|
@@ -4809,6 +5114,32 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4809
5114
|
const width = revision.sourceWidth;
|
|
4810
5115
|
const height = revision.sourceHeight;
|
|
4811
5116
|
const roles = revision.sourceMembers?.map((member) => member.role);
|
|
5117
|
+
if (revision.engine === "pro-flash") {
|
|
5118
|
+
if (revision.mode === "inpaint") {
|
|
5119
|
+
if (!revision.maskFile || !revision.maskSha256 || !revision.maskFormat) {
|
|
5120
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask is not ready`);
|
|
5121
|
+
}
|
|
5122
|
+
const maskBytes = (0, import_node_fs2.readFileSync)(revision.maskFile);
|
|
5123
|
+
if (sha256(maskBytes) !== revision.maskSha256) {
|
|
5124
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask changed after the manifest was resolved`);
|
|
5125
|
+
}
|
|
5126
|
+
const res3 = await this.client.inpaintImageProFlash({
|
|
5127
|
+
image,
|
|
5128
|
+
maskImage: { base64: maskBytes.toString("base64"), format: revision.maskFormat },
|
|
5129
|
+
description: spec.prompt,
|
|
5130
|
+
noBackground: spec.noBackground,
|
|
5131
|
+
seed: spec.seed
|
|
5132
|
+
});
|
|
5133
|
+
return { jobId: res3.background_job_id, metadata: { imageProFlash: proFlashRecord(res3) } };
|
|
5134
|
+
}
|
|
5135
|
+
const res2 = await this.client.editImageProFlash({
|
|
5136
|
+
image,
|
|
5137
|
+
description: spec.prompt,
|
|
5138
|
+
noBackground: spec.noBackground,
|
|
5139
|
+
seed: spec.seed
|
|
5140
|
+
});
|
|
5141
|
+
return { jobId: res2.background_job_id, metadata: { imageProFlash: proFlashRecord(res2) } };
|
|
5142
|
+
}
|
|
4812
5143
|
if (revision.mode === "inpaint") {
|
|
4813
5144
|
if (!revision.maskFile || !revision.maskSha256 || !revision.maskFormat) {
|
|
4814
5145
|
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask is not ready`);
|
|
@@ -4904,6 +5235,27 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4904
5235
|
});
|
|
4905
5236
|
return { jobId: res2.background_job_id };
|
|
4906
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
|
+
}
|
|
4907
5259
|
if (revision.strength != null) {
|
|
4908
5260
|
throw new Error(
|
|
4909
5261
|
`${spec.styleId}/${spec.assetId}: PixelLab image-to-image revisions take no strength; edit-images-v2 always applies the full instruction`
|
|
@@ -4969,10 +5321,11 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4969
5321
|
if (revisionMode === "reduce-colors" || revisionMode === "correct-pixelart") {
|
|
4970
5322
|
return this.pollCachedRevision(jobId, context);
|
|
4971
5323
|
}
|
|
4972
|
-
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") {
|
|
4973
5325
|
return this.pollAnimateRevision(jobId, context);
|
|
4974
5326
|
}
|
|
4975
5327
|
if (context?.spec?.revision) return this.pollRevision(jobId);
|
|
5328
|
+
if (generator === "imageProFlash") return this.pollRevision(jobId);
|
|
4976
5329
|
if (generator === "pixflux") {
|
|
4977
5330
|
const file = import_node_path.default.join(_PixelLabProvider.cacheDir(), `${jobId}.png`);
|
|
4978
5331
|
if ((0, import_node_fs2.existsSync)(file)) {
|
|
@@ -5553,6 +5906,13 @@ function readPose(spec, what, image) {
|
|
|
5553
5906
|
}
|
|
5554
5907
|
return { base64: bytes.toString("base64"), format: image.format };
|
|
5555
5908
|
}
|
|
5909
|
+
function proFlashRecord(res) {
|
|
5910
|
+
return {
|
|
5911
|
+
imageId: res.image_id,
|
|
5912
|
+
sourceImageId: res.source_image_id,
|
|
5913
|
+
...res.estimated_generations != null ? { estimatedGenerations: res.estimated_generations } : {}
|
|
5914
|
+
};
|
|
5915
|
+
}
|
|
5556
5916
|
function editAnimationFrameCeiling(width, height) {
|
|
5557
5917
|
const side = Math.max(width, height);
|
|
5558
5918
|
if (side <= 64) return 16;
|
|
@@ -6696,11 +7056,12 @@ var ComfyUIProvider = class _ComfyUIProvider {
|
|
|
6696
7056
|
/**
|
|
6697
7057
|
* Everything else resolves generically to whatever the user's own
|
|
6698
7058
|
* workflow does with `bindings.sourceImage`. The frame-set modes
|
|
6699
|
-
* (`animate`, `animate-pixminimax`, `
|
|
6700
|
-
* the exception: they produce an ordered frame set,
|
|
6701
|
-
* revision path always writes a single output image
|
|
6702
|
-
* below) — a real structural gap, not a missing
|
|
6703
|
-
* 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.
|
|
6704
7065
|
*/
|
|
6705
7066
|
supportsRevision(mode2) {
|
|
6706
7067
|
return !FRAME_SET_REVISION_MODES.includes(mode2);
|
|
@@ -6756,6 +7117,11 @@ var ComfyUIProvider = class _ComfyUIProvider {
|
|
|
6756
7117
|
throw new Error("ComfyUI providerOptions.frames requires generator: frames");
|
|
6757
7118
|
}
|
|
6758
7119
|
if (spec.revision) {
|
|
7120
|
+
if (spec.revision.engine) {
|
|
7121
|
+
throw new Error(
|
|
7122
|
+
`ComfyUI has no "${spec.revision.engine}" revision engine; that selects PixelLab's Pro Flash edit/inpaint endpoints. Drop engine to run the revision through this style's own workflow.`
|
|
7123
|
+
);
|
|
7124
|
+
}
|
|
6759
7125
|
if (spec.revision.sourceMembers) {
|
|
6760
7126
|
throw new Error(
|
|
6761
7127
|
`ComfyUI revisions read one source image; ${spec.revision.sourceAssetId} is a ${spec.revision.sourceMembers.length}-member set (directions or frames)`
|
|
@@ -8353,6 +8719,7 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8353
8719
|
uiPieces: generator === "uiAsset" ? asset.pieces : void 0,
|
|
8354
8720
|
uiElements: generator === "uiAsset" ? asset.elements : void 0,
|
|
8355
8721
|
uiColorPalette: generator === "uiAsset" || generator === "uiElement" ? style.uiColorPalette : void 0,
|
|
8722
|
+
...generator === "imageProFlash" && style.styleTraits ? { styleTraits: style.styleTraits } : {},
|
|
8356
8723
|
palette: style.palette,
|
|
8357
8724
|
enforcePalette: style.enforcePalette,
|
|
8358
8725
|
noBackground: style.noBackground,
|
|
@@ -8597,6 +8964,8 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8597
8964
|
const paletteImage = paletteImageFile ? await optionalRevisionImage(paletteImageFile, "revision palette image", "png") : null;
|
|
8598
8965
|
const lastFrameFile = asset.revision.lastFrame ? import_node_path5.default.resolve(root, asset.revision.lastFrame) : void 0;
|
|
8599
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;
|
|
8600
8969
|
resolved.revision = {
|
|
8601
8970
|
mode: asset.revision.mode,
|
|
8602
8971
|
sourceAssetId: asset.revision.from,
|
|
@@ -8636,7 +9005,20 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8636
9005
|
lastFrameFormat: lastFrame?.format ?? null
|
|
8637
9006
|
} : {},
|
|
8638
9007
|
...asset.revision.direction ? { direction: asset.revision.direction } : {},
|
|
8639
|
-
...asset.revision.enhancePrompt == null ? {} : { enhancePrompt: asset.revision.enhancePrompt }
|
|
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 } : {},
|
|
9021
|
+
...asset.revision.engine ? { engine: asset.revision.engine } : {}
|
|
8640
9022
|
};
|
|
8641
9023
|
}
|
|
8642
9024
|
if (asset.batch) {
|
|
@@ -8757,6 +9139,17 @@ async function optionalRevisionImage(file, label, requiredFormat) {
|
|
|
8757
9139
|
}
|
|
8758
9140
|
return { hash: sha256(bytes), ...metadata };
|
|
8759
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
|
+
}
|
|
8760
9153
|
async function revisionSourceMembers(stem, label) {
|
|
8761
9154
|
if ((0, import_node_fs5.existsSync)(stem)) return null;
|
|
8762
9155
|
const at = (role) => memberPath(stem, role, 0, 2, MediaType.PNG);
|
|
@@ -10879,47 +11272,47 @@ var import_node_path14 = __toESM(require("path"), 1);
|
|
|
10879
11272
|
var import_node_fs10 = require("fs");
|
|
10880
11273
|
var import_promises7 = require("fs/promises");
|
|
10881
11274
|
var import_node_url = require("url");
|
|
10882
|
-
var
|
|
11275
|
+
var import_zod4 = require("zod");
|
|
10883
11276
|
var SHA256_RE = /^[0-9a-f]{64}$/;
|
|
10884
11277
|
var RECIPE_ID_RE = /^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/;
|
|
10885
11278
|
var VERSION_RE = /^\d+\.\d+\.\d+$/;
|
|
10886
11279
|
var RECIPE_FILE = "pixelkiln.recipe.json";
|
|
10887
11280
|
var RECIPE_DIR_TOKEN = "{{recipeDir}}";
|
|
10888
|
-
var PortablePathSchema =
|
|
11281
|
+
var PortablePathSchema = import_zod4.z.string().min(1).refine((value) => {
|
|
10889
11282
|
if (value.includes("\\") || import_node_path14.default.posix.isAbsolute(value)) return false;
|
|
10890
11283
|
const parts = value.split("/");
|
|
10891
11284
|
return !parts.includes("") && !parts.includes(".") && !parts.includes("..");
|
|
10892
11285
|
}, "expected a portable relative path without '.', '..', or backslashes");
|
|
10893
|
-
var RecipeBindingSchema =
|
|
10894
|
-
nodeId:
|
|
10895
|
-
input:
|
|
11286
|
+
var RecipeBindingSchema = import_zod4.z.object({
|
|
11287
|
+
nodeId: import_zod4.z.string().min(1),
|
|
11288
|
+
input: import_zod4.z.string().min(1)
|
|
10896
11289
|
}).strict();
|
|
10897
|
-
var RecipeSchema =
|
|
10898
|
-
$schema:
|
|
10899
|
-
format:
|
|
10900
|
-
schemaVersion:
|
|
10901
|
-
id:
|
|
10902
|
-
version:
|
|
10903
|
-
provider:
|
|
10904
|
-
summary:
|
|
10905
|
-
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({
|
|
10906
11299
|
path: PortablePathSchema,
|
|
10907
|
-
role:
|
|
10908
|
-
sha256:
|
|
11300
|
+
role: import_zod4.z.enum(["workflow", "reference"]),
|
|
11301
|
+
sha256: import_zod4.z.string().regex(SHA256_RE)
|
|
10909
11302
|
}).strict()).default([]),
|
|
10910
|
-
models:
|
|
11303
|
+
models: import_zod4.z.array(import_zod4.z.object({
|
|
10911
11304
|
path: PortablePathSchema,
|
|
10912
|
-
sha256:
|
|
10913
|
-
source:
|
|
10914
|
-
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)
|
|
10915
11308
|
}).strict()).default([]),
|
|
10916
|
-
styleId:
|
|
11309
|
+
styleId: import_zod4.z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
10917
11310
|
style: StyleSchema,
|
|
10918
|
-
workflow:
|
|
11311
|
+
workflow: import_zod4.z.object({
|
|
10919
11312
|
path: PortablePathSchema,
|
|
10920
|
-
outputNodeId:
|
|
10921
|
-
numImages:
|
|
10922
|
-
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({
|
|
10923
11316
|
prompt: RecipeBindingSchema,
|
|
10924
11317
|
width: RecipeBindingSchema.optional(),
|
|
10925
11318
|
height: RecipeBindingSchema.optional(),
|
|
@@ -10930,67 +11323,67 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
10930
11323
|
strength: RecipeBindingSchema.optional()
|
|
10931
11324
|
}).strict()
|
|
10932
11325
|
}).strict().optional(),
|
|
10933
|
-
quality:
|
|
10934
|
-
stage:
|
|
10935
|
-
workingCanvas:
|
|
10936
|
-
width:
|
|
10937
|
-
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)
|
|
10938
11331
|
}).strict(),
|
|
10939
|
-
recommendedNativeSize:
|
|
10940
|
-
min:
|
|
10941
|
-
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)
|
|
10942
11335
|
}).strict(),
|
|
10943
|
-
paletteColors:
|
|
10944
|
-
min:
|
|
10945
|
-
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)
|
|
10946
11339
|
}).strict(),
|
|
10947
|
-
background:
|
|
10948
|
-
checks:
|
|
11340
|
+
background: import_zod4.z.enum(["opaque", "transparent", "full-bleed"]),
|
|
11341
|
+
checks: import_zod4.z.array(import_zod4.z.enum([
|
|
10949
11342
|
"prompt-coverage",
|
|
10950
11343
|
"native-grid",
|
|
10951
11344
|
"final-palette",
|
|
10952
11345
|
"alpha-edge",
|
|
10953
11346
|
"human-1x"
|
|
10954
11347
|
])).min(1),
|
|
10955
|
-
notes:
|
|
11348
|
+
notes: import_zod4.z.array(import_zod4.z.string().min(1)).default([])
|
|
10956
11349
|
}).strict(),
|
|
10957
|
-
integrity:
|
|
10958
|
-
algorithm:
|
|
10959
|
-
digest:
|
|
11350
|
+
integrity: import_zod4.z.object({
|
|
11351
|
+
algorithm: import_zod4.z.literal("sha256"),
|
|
11352
|
+
digest: import_zod4.z.string().regex(SHA256_RE)
|
|
10960
11353
|
}).strict()
|
|
10961
11354
|
}).strict().superRefine((recipe, context) => {
|
|
10962
11355
|
if (recipe.style.provider && recipe.style.provider !== recipe.provider) {
|
|
10963
11356
|
context.addIssue({
|
|
10964
|
-
code:
|
|
11357
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
10965
11358
|
path: ["style", "provider"],
|
|
10966
11359
|
message: "must match the recipe provider"
|
|
10967
11360
|
});
|
|
10968
11361
|
}
|
|
10969
11362
|
const filePaths = recipe.files.map((file) => file.path);
|
|
10970
11363
|
if (new Set(filePaths).size !== filePaths.length) {
|
|
10971
|
-
context.addIssue({ code:
|
|
11364
|
+
context.addIssue({ code: import_zod4.z.ZodIssueCode.custom, path: ["files"], message: "duplicate file path" });
|
|
10972
11365
|
}
|
|
10973
11366
|
const modelPaths = recipe.models.map((model) => model.path);
|
|
10974
11367
|
if (new Set(modelPaths).size !== modelPaths.length) {
|
|
10975
|
-
context.addIssue({ code:
|
|
11368
|
+
context.addIssue({ code: import_zod4.z.ZodIssueCode.custom, path: ["models"], message: "duplicate model path" });
|
|
10976
11369
|
}
|
|
10977
11370
|
if (filePaths.includes(RECIPE_FILE)) {
|
|
10978
11371
|
context.addIssue({
|
|
10979
|
-
code:
|
|
11372
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
10980
11373
|
path: ["files"],
|
|
10981
11374
|
message: `${RECIPE_FILE} cannot hash itself`
|
|
10982
11375
|
});
|
|
10983
11376
|
}
|
|
10984
11377
|
if (recipe.quality.recommendedNativeSize.min > recipe.quality.recommendedNativeSize.max) {
|
|
10985
11378
|
context.addIssue({
|
|
10986
|
-
code:
|
|
11379
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
10987
11380
|
path: ["quality", "recommendedNativeSize"],
|
|
10988
11381
|
message: "min cannot exceed max"
|
|
10989
11382
|
});
|
|
10990
11383
|
}
|
|
10991
11384
|
if (recipe.quality.paletteColors.min > recipe.quality.paletteColors.max) {
|
|
10992
11385
|
context.addIssue({
|
|
10993
|
-
code:
|
|
11386
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
10994
11387
|
path: ["quality", "paletteColors"],
|
|
10995
11388
|
message: "min cannot exceed max"
|
|
10996
11389
|
});
|
|
@@ -10999,7 +11392,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
10999
11392
|
(file) => file.path === recipe.workflow.path && file.role === "workflow"
|
|
11000
11393
|
)) {
|
|
11001
11394
|
context.addIssue({
|
|
11002
|
-
code:
|
|
11395
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11003
11396
|
path: ["workflow", "path"],
|
|
11004
11397
|
message: "must name a file whose role is workflow"
|
|
11005
11398
|
});
|
|
@@ -11007,7 +11400,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11007
11400
|
if (recipe.provider === "comfyui") {
|
|
11008
11401
|
if (!recipe.workflow) {
|
|
11009
11402
|
context.addIssue({
|
|
11010
|
-
code:
|
|
11403
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11011
11404
|
path: ["workflow"],
|
|
11012
11405
|
message: "ComfyUI recipes require workflow metadata"
|
|
11013
11406
|
});
|
|
@@ -11016,7 +11409,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11016
11409
|
const options = recipe.style.providerOptions.comfyui;
|
|
11017
11410
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
11018
11411
|
context.addIssue({
|
|
11019
|
-
code:
|
|
11412
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11020
11413
|
path: ["style", "providerOptions", "comfyui"],
|
|
11021
11414
|
message: "ComfyUI recipes require ComfyUI provider options"
|
|
11022
11415
|
});
|
|
@@ -11030,7 +11423,7 @@ var RecipeSchema = import_zod3.z.object({
|
|
|
11030
11423
|
};
|
|
11031
11424
|
if (JSON.stringify(canonical3(options)) !== JSON.stringify(canonical3(expected))) {
|
|
11032
11425
|
context.addIssue({
|
|
11033
|
-
code:
|
|
11426
|
+
code: import_zod4.z.ZodIssueCode.custom,
|
|
11034
11427
|
path: ["style", "providerOptions", "comfyui"],
|
|
11035
11428
|
message: "must match workflow metadata and use {{recipeDir}} for workflowFile"
|
|
11036
11429
|
});
|
|
@@ -11468,11 +11861,11 @@ async function generateFont(client2, opts) {
|
|
|
11468
11861
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
11469
11862
|
var import_node_fs13 = require("fs");
|
|
11470
11863
|
var import_promises10 = require("fs/promises");
|
|
11471
|
-
var
|
|
11864
|
+
var import_zod5 = require("zod");
|
|
11472
11865
|
var SHA256_RE2 = /^[0-9a-f]{64}$/;
|
|
11473
11866
|
var HEX_RE = /^#[0-9a-f]{6}$/;
|
|
11474
11867
|
var MAX_REDMEAN_DISTANCE = 765;
|
|
11475
|
-
var QualityPathSchema =
|
|
11868
|
+
var QualityPathSchema = import_zod5.z.string().min(1).refine(
|
|
11476
11869
|
(value) => !import_node_path17.default.posix.isAbsolute(value) && !value.includes("\\"),
|
|
11477
11870
|
"expected a portable relative path"
|
|
11478
11871
|
);
|
|
@@ -11486,53 +11879,53 @@ var DEFAULT_QUALITY_TOLERANCES = {
|
|
|
11486
11879
|
maxEdgeContrastDrop: 0.03,
|
|
11487
11880
|
maxIsolatedPixelIncrease: 5e-3
|
|
11488
11881
|
};
|
|
11489
|
-
var QualityToleranceSchema =
|
|
11490
|
-
requireExactHash:
|
|
11491
|
-
maxColorCountIncrease:
|
|
11492
|
-
maxNewColors:
|
|
11493
|
-
maxTransparencyDelta:
|
|
11494
|
-
maxPartialAlphaIncrease:
|
|
11495
|
-
maxEdgeDensityDelta:
|
|
11496
|
-
maxEdgeContrastDrop:
|
|
11497
|
-
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)
|
|
11498
11891
|
}).strict();
|
|
11499
|
-
var ImageQualityMetricsSchema =
|
|
11500
|
-
sha256:
|
|
11501
|
-
width:
|
|
11502
|
-
height:
|
|
11503
|
-
colorCount:
|
|
11504
|
-
colors:
|
|
11505
|
-
transparency:
|
|
11506
|
-
partialAlpha:
|
|
11507
|
-
edgeDensity:
|
|
11508
|
-
meanEdgeContrast:
|
|
11509
|
-
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)
|
|
11510
11903
|
}).strict();
|
|
11511
|
-
var QualityBaselineCaseSchema =
|
|
11512
|
-
id:
|
|
11904
|
+
var QualityBaselineCaseSchema = import_zod5.z.object({
|
|
11905
|
+
id: import_zod5.z.string().regex(/^[a-z0-9][a-z0-9/_-]*$/),
|
|
11513
11906
|
file: QualityPathSchema,
|
|
11514
|
-
record:
|
|
11907
|
+
record: import_zod5.z.object({
|
|
11515
11908
|
path: QualityPathSchema,
|
|
11516
|
-
sha256:
|
|
11909
|
+
sha256: import_zod5.z.string().regex(SHA256_RE2)
|
|
11517
11910
|
}).strict().optional(),
|
|
11518
11911
|
expected: ImageQualityMetricsSchema,
|
|
11519
11912
|
tolerances: QualityToleranceSchema
|
|
11520
11913
|
}).strict();
|
|
11521
|
-
var QualityBaselineSchema =
|
|
11522
|
-
$schema:
|
|
11523
|
-
format:
|
|
11524
|
-
schemaVersion:
|
|
11525
|
-
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)
|
|
11526
11919
|
}).strict().superRefine((baseline, context) => {
|
|
11527
11920
|
const ids = baseline.cases.map((entry) => entry.id);
|
|
11528
11921
|
if (new Set(ids).size !== ids.length) {
|
|
11529
|
-
context.addIssue({ code:
|
|
11922
|
+
context.addIssue({ code: import_zod5.z.ZodIssueCode.custom, path: ["cases"], message: "duplicate case id" });
|
|
11530
11923
|
}
|
|
11531
11924
|
});
|
|
11532
|
-
var QualityInputSchema =
|
|
11533
|
-
id:
|
|
11534
|
-
path:
|
|
11535
|
-
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(),
|
|
11536
11929
|
tolerances: QualityToleranceSchema.partial().optional()
|
|
11537
11930
|
}).strict();
|
|
11538
11931
|
function message4(error) {
|
|
@@ -11634,7 +12027,7 @@ async function measureImageQuality(file) {
|
|
|
11634
12027
|
}
|
|
11635
12028
|
}
|
|
11636
12029
|
function resolveQualityInputs(raw, inputsFilePath) {
|
|
11637
|
-
const parsed =
|
|
12030
|
+
const parsed = import_zod5.z.array(QualityInputSchema).min(1).safeParse(raw);
|
|
11638
12031
|
if (!parsed.success) {
|
|
11639
12032
|
throw new Error(
|
|
11640
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")
|
|
@@ -11857,11 +12250,11 @@ var import_node_path21 = __toESM(require("path"), 1);
|
|
|
11857
12250
|
var import_promises11 = require("fs/promises");
|
|
11858
12251
|
var import_node_fs14 = require("fs");
|
|
11859
12252
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
11860
|
-
var
|
|
11861
|
-
var HashCacheSchema =
|
|
11862
|
-
version:
|
|
12253
|
+
var import_zod6 = require("zod");
|
|
12254
|
+
var HashCacheSchema = import_zod6.z.object({
|
|
12255
|
+
version: import_zod6.z.literal(1),
|
|
11863
12256
|
/** objectId → sha256 of that object's image bytes. */
|
|
11864
|
-
hashes:
|
|
12257
|
+
hashes: import_zod6.z.record(import_zod6.z.string())
|
|
11865
12258
|
});
|
|
11866
12259
|
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
11867
12260
|
function isSha256Hash(value) {
|
|
@@ -13408,7 +13801,11 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13408
13801
|
...spec.revision.fps == null ? {} : { fps: spec.revision.fps },
|
|
13409
13802
|
...spec.revision.lastFrameSha256 ? { lastFrameSha256: spec.revision.lastFrameSha256 } : {},
|
|
13410
13803
|
...spec.revision.direction ? { direction: spec.revision.direction } : {},
|
|
13411
|
-
...spec.revision.enhancePrompt == null ? {} : { enhancePrompt: spec.revision.enhancePrompt }
|
|
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 } : {},
|
|
13808
|
+
...spec.revision.engine ? { engine: spec.revision.engine } : {}
|
|
13412
13809
|
} : null,
|
|
13413
13810
|
outfit: spec.character?.kind === "outfit" && outfitParentEntry ? {
|
|
13414
13811
|
sourceAssetId: spec.character.parentAssetId,
|
|
@@ -13452,8 +13849,10 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13452
13849
|
path: currentEntryOutputPath(parentEntry, spec.character.parentSpec, index),
|
|
13453
13850
|
role: output.role
|
|
13454
13851
|
})) : void 0;
|
|
13852
|
+
const referenceSourceImageId = ownedReferenceImageId(spec, lock, provider.id);
|
|
13455
13853
|
const { jobId, metadata } = await provider.submit(spec, refs, {
|
|
13456
13854
|
...previousJobId ? { previousJobId } : {},
|
|
13855
|
+
...referenceSourceImageId ? { referenceSourceImageId } : {},
|
|
13457
13856
|
...parentEntry?.objectId ? { parentObjectId: parentEntry.objectId } : {},
|
|
13458
13857
|
...anchorEntry?.objectId ? { styleObjectId: anchorEntry.objectId } : {},
|
|
13459
13858
|
...parentOutputs ? { parentOutputs } : {},
|
|
@@ -13520,6 +13919,17 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13520
13919
|
}
|
|
13521
13920
|
return { submitted, failed, spent, unit };
|
|
13522
13921
|
}
|
|
13922
|
+
function ownedReferenceImageId(spec, lock, providerId) {
|
|
13923
|
+
const sha2562 = spec.character?.kind === "base" && spec.character.mode === "pro-flash" ? spec.character.reference?.south?.sha256 : spec.objectPro?.kind === "base" ? spec.objectPro.reference?.sha256 : void 0;
|
|
13924
|
+
if (!sha2562) return void 0;
|
|
13925
|
+
for (const entry of Object.values(lock.entries)) {
|
|
13926
|
+
if (entry.provider !== providerId || entry.generator !== "imageProFlash" || entry.status !== "downloaded") continue;
|
|
13927
|
+
if (entry.outputs.length !== 1 || entry.outputs[0].sha256 !== sha2562) continue;
|
|
13928
|
+
const recorded = entry.providerMetadata?.[providerId]?.imageProFlash;
|
|
13929
|
+
if (typeof recorded?.sourceImageId === "string" && recorded.sourceImageId) return recorded.sourceImageId;
|
|
13930
|
+
}
|
|
13931
|
+
return void 0;
|
|
13932
|
+
}
|
|
13523
13933
|
|
|
13524
13934
|
// src/pipeline/poll.ts
|
|
13525
13935
|
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -14692,20 +15102,20 @@ var import_node_path30 = __toESM(require("path"), 1);
|
|
|
14692
15102
|
var import_promises19 = require("fs/promises");
|
|
14693
15103
|
var import_node_fs23 = require("fs");
|
|
14694
15104
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
14695
|
-
var
|
|
14696
|
-
var WorkspaceProjectSchema =
|
|
14697
|
-
id:
|
|
15105
|
+
var import_zod7 = require("zod");
|
|
15106
|
+
var WorkspaceProjectSchema = import_zod7.z.object({
|
|
15107
|
+
id: import_zod7.z.string().min(1),
|
|
14698
15108
|
/** Manifest path, relative to the catalog file's own directory. */
|
|
14699
|
-
manifest:
|
|
15109
|
+
manifest: import_zod7.z.string().min(1),
|
|
14700
15110
|
/** Lockfile path, relative to the catalog file's own directory. */
|
|
14701
|
-
lock:
|
|
14702
|
-
provider:
|
|
15111
|
+
lock: import_zod7.z.string().min(1),
|
|
15112
|
+
provider: import_zod7.z.string().min(1).default("pixellab"),
|
|
14703
15113
|
/** Free-form label for a shared account, e.g. distinguishing sandboxes. */
|
|
14704
|
-
account:
|
|
15114
|
+
account: import_zod7.z.string().optional()
|
|
14705
15115
|
}).strict();
|
|
14706
|
-
var WorkspaceSchema =
|
|
14707
|
-
version:
|
|
14708
|
-
projects:
|
|
15116
|
+
var WorkspaceSchema = import_zod7.z.object({
|
|
15117
|
+
version: import_zod7.z.literal(1),
|
|
15118
|
+
projects: import_zod7.z.array(WorkspaceProjectSchema).default([])
|
|
14709
15119
|
}).strict();
|
|
14710
15120
|
function parseWorkspace(raw) {
|
|
14711
15121
|
const parsed = WorkspaceSchema.safeParse(raw);
|
|
@@ -14823,62 +15233,62 @@ function validateWorkspace(ws, dir) {
|
|
|
14823
15233
|
|
|
14824
15234
|
// src/gallery/edit.ts
|
|
14825
15235
|
var import_node_path29 = __toESM(require("path"), 1);
|
|
14826
|
-
var
|
|
15236
|
+
var import_zod10 = require("zod");
|
|
14827
15237
|
|
|
14828
15238
|
// src/manifest-edit.ts
|
|
14829
15239
|
var import_promises20 = require("fs/promises");
|
|
14830
15240
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
14831
|
-
var
|
|
14832
|
-
var HexSha =
|
|
14833
|
-
var AssetPatchSchema =
|
|
14834
|
-
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(),
|
|
14835
15245
|
/** Per-style override for the style being viewed; null removes it. */
|
|
14836
|
-
promptForStyle:
|
|
14837
|
-
category:
|
|
14838
|
-
width:
|
|
14839
|
-
height:
|
|
14840
|
-
size:
|
|
14841
|
-
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()
|
|
14842
15252
|
}).strict();
|
|
14843
|
-
var NewStateSchema =
|
|
15253
|
+
var NewStateSchema = import_zod8.z.object({
|
|
14844
15254
|
/** Asset id of the parent this states; must already exist. */
|
|
14845
|
-
of:
|
|
14846
|
-
paletteFromReference:
|
|
14847
|
-
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()
|
|
14848
15258
|
}).strict();
|
|
14849
|
-
var NewAnimationSchema =
|
|
15259
|
+
var NewAnimationSchema = import_zod8.z.object({
|
|
14850
15260
|
/** Asset id of the parent this animates; must already exist. */
|
|
14851
|
-
of:
|
|
15261
|
+
of: import_zod8.z.string().min(1),
|
|
14852
15262
|
/** A PixelLab template id (`character` only; `objectPro` has no template concept). */
|
|
14853
|
-
template:
|
|
15263
|
+
template: import_zod8.z.string().min(1).optional(),
|
|
14854
15264
|
direction: CharacterDirectionSchema.optional(),
|
|
14855
|
-
frames:
|
|
14856
|
-
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(),
|
|
14857
15267
|
mode: CharacterAnimationModeSchema.optional(),
|
|
14858
15268
|
/** What is being animated, when the parent's own description would mislead the model (`character` only). */
|
|
14859
|
-
subject:
|
|
14860
|
-
enhancePrompt:
|
|
15269
|
+
subject: import_zod8.z.string().min(1).optional(),
|
|
15270
|
+
enhancePrompt: import_zod8.z.boolean().optional()
|
|
14861
15271
|
}).strict();
|
|
14862
|
-
var NewAssetSchema =
|
|
14863
|
-
prompt:
|
|
14864
|
-
category:
|
|
14865
|
-
width:
|
|
14866
|
-
height:
|
|
14867
|
-
size:
|
|
14868
|
-
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(),
|
|
14869
15279
|
/** Restrict to these styles; empty or omitted means every style. */
|
|
14870
|
-
styles:
|
|
15280
|
+
styles: import_zod8.z.array(import_zod8.z.string().min(1)).optional(),
|
|
14871
15281
|
/**
|
|
14872
15282
|
* A controlled regeneration of another asset in the same manifest,
|
|
14873
15283
|
* instead of a fresh generation. `inpaint` needs a mask upload the
|
|
14874
15284
|
* gallery does not offer yet, so only `image-to-image` can be created
|
|
14875
15285
|
* here; hand-edit the manifest for the other modes.
|
|
14876
15286
|
*/
|
|
14877
|
-
revision:
|
|
14878
|
-
mode:
|
|
15287
|
+
revision: import_zod8.z.object({
|
|
15288
|
+
mode: import_zod8.z.literal("image-to-image"),
|
|
14879
15289
|
/** Asset id of the parent this revises; must already exist. */
|
|
14880
|
-
from:
|
|
14881
|
-
strength:
|
|
15290
|
+
from: import_zod8.z.string().min(1),
|
|
15291
|
+
strength: import_zod8.z.number().min(0).max(1).optional()
|
|
14882
15292
|
}).strict().optional(),
|
|
14883
15293
|
/** A pose or outfit of an existing `character`/`objectPro` base or state. */
|
|
14884
15294
|
state: NewStateSchema.optional(),
|
|
@@ -14894,58 +15304,58 @@ var CANDIDATE_OPTION = {
|
|
|
14894
15304
|
comfyui: "numImages",
|
|
14895
15305
|
scenario: "numOutputs"
|
|
14896
15306
|
};
|
|
14897
|
-
var ManifestEditSchema =
|
|
14898
|
-
|
|
14899
|
-
action:
|
|
15307
|
+
var ManifestEditSchema = import_zod8.z.discriminatedUnion("action", [
|
|
15308
|
+
import_zod8.z.object({
|
|
15309
|
+
action: import_zod8.z.literal("patch-asset"),
|
|
14900
15310
|
/** Workspace project id; omitted for a single-project gallery. */
|
|
14901
|
-
project:
|
|
14902
|
-
assetId:
|
|
15311
|
+
project: import_zod8.z.string().min(1).optional(),
|
|
15312
|
+
assetId: import_zod8.z.string().min(1),
|
|
14903
15313
|
/** Manifest bytes the page last saw; a mismatch refuses the write. */
|
|
14904
15314
|
expectedSha256: HexSha,
|
|
14905
15315
|
patch: AssetPatchSchema
|
|
14906
15316
|
}).strict(),
|
|
14907
|
-
|
|
14908
|
-
action:
|
|
14909
|
-
project:
|
|
14910
|
-
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"),
|
|
14911
15321
|
expectedSha256: HexSha,
|
|
14912
15322
|
asset: NewAssetSchema
|
|
14913
15323
|
}).strict(),
|
|
14914
|
-
|
|
14915
|
-
action:
|
|
14916
|
-
project:
|
|
14917
|
-
assetId:
|
|
14918
|
-
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),
|
|
14919
15329
|
/** Manifest-relative path of the art that stands in for this asset in this style. */
|
|
14920
|
-
source:
|
|
15330
|
+
source: import_zod8.z.string().min(1),
|
|
14921
15331
|
expectedSha256: HexSha
|
|
14922
15332
|
}).strict(),
|
|
14923
|
-
|
|
14924
|
-
action:
|
|
14925
|
-
project:
|
|
14926
|
-
assetId:
|
|
14927
|
-
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),
|
|
14928
15338
|
expectedSha256: HexSha
|
|
14929
15339
|
}).strict(),
|
|
14930
|
-
|
|
14931
|
-
action:
|
|
14932
|
-
project:
|
|
14933
|
-
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),
|
|
14934
15344
|
expectedSha256: HexSha,
|
|
14935
|
-
patch:
|
|
15345
|
+
patch: import_zod8.z.object({
|
|
14936
15346
|
/** Candidates per generation, written to the provider's own option. */
|
|
14937
|
-
candidates:
|
|
15347
|
+
candidates: import_zod8.z.number().int().min(1).max(64).optional(),
|
|
14938
15348
|
/** Empty clears the style's own value (inherit, or the default). */
|
|
14939
|
-
promptPrefix:
|
|
14940
|
-
promptSuffix:
|
|
15349
|
+
promptPrefix: import_zod8.z.string().optional(),
|
|
15350
|
+
promptSuffix: import_zod8.z.string().optional(),
|
|
14941
15351
|
/** `#rrggbb` values; null or empty clears the style's own palette. */
|
|
14942
|
-
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(),
|
|
14943
15353
|
/** Snap downloaded art to the palette; false clears the style's own value. */
|
|
14944
|
-
enforcePalette:
|
|
15354
|
+
enforcePalette: import_zod8.z.boolean().optional(),
|
|
14945
15355
|
/** Provider view name (PixelLab: low top-down, high top-down, side); empty clears. */
|
|
14946
|
-
view:
|
|
15356
|
+
view: import_zod8.z.string().max(64).nullable().optional(),
|
|
14947
15357
|
/** pixflux only; null clears the style's own value. */
|
|
14948
|
-
noBackground:
|
|
15358
|
+
noBackground: import_zod8.z.boolean().nullable().optional()
|
|
14949
15359
|
}).strict().refine((patch) => Object.keys(patch).length > 0, { message: "nothing to change" })
|
|
14950
15360
|
}).strict()
|
|
14951
15361
|
]);
|
|
@@ -15139,7 +15549,7 @@ async function applyManifestEdit(manifestPath, edit) {
|
|
|
15139
15549
|
var import_node_fs24 = require("fs");
|
|
15140
15550
|
var import_promises21 = require("fs/promises");
|
|
15141
15551
|
var import_node_path28 = __toESM(require("path"), 1);
|
|
15142
|
-
var
|
|
15552
|
+
var import_zod9 = require("zod");
|
|
15143
15553
|
var HAND_EDIT_DIR = "edits";
|
|
15144
15554
|
function handEditPath(loaded, spec) {
|
|
15145
15555
|
const style = loaded.manifest.styles[spec.styleId];
|
|
@@ -15236,35 +15646,35 @@ async function detachHandEdit(loaded, spec, opts = {}) {
|
|
|
15236
15646
|
});
|
|
15237
15647
|
return { manifestSha256: result.sha256, changed: result.changed };
|
|
15238
15648
|
}
|
|
15239
|
-
var CompanionOutputSchema =
|
|
15649
|
+
var CompanionOutputSchema = import_zod9.z.object({
|
|
15240
15650
|
/** Output role for a set member; null for a single image. */
|
|
15241
|
-
role:
|
|
15651
|
+
role: import_zod9.z.string().nullable(),
|
|
15242
15652
|
/** sha256 of the generated file this member started from; null when it started from untracked art. */
|
|
15243
|
-
basedOn:
|
|
15653
|
+
basedOn: import_zod9.z.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
15244
15654
|
/** sha256 of the member as saved, so a later change by another tool is visible. */
|
|
15245
|
-
sha256:
|
|
15655
|
+
sha256: import_zod9.z.string().regex(/^[0-9a-f]{64}$/)
|
|
15246
15656
|
}).strict();
|
|
15247
|
-
var CompanionV2Schema =
|
|
15248
|
-
version:
|
|
15657
|
+
var CompanionV2Schema = import_zod9.z.object({
|
|
15658
|
+
version: import_zod9.z.literal(2),
|
|
15249
15659
|
/** Editor identity the bridge reported, e.g. `pixelorama@v1.2.2-stable`. */
|
|
15250
|
-
editor:
|
|
15251
|
-
protocol:
|
|
15252
|
-
savedAt:
|
|
15660
|
+
editor: import_zod9.z.string().min(1),
|
|
15661
|
+
protocol: import_zod9.z.number().int().positive(),
|
|
15662
|
+
savedAt: import_zod9.z.string().datetime(),
|
|
15253
15663
|
/** Basename of the layered project file beside the edit, when one was kept. */
|
|
15254
|
-
project:
|
|
15664
|
+
project: import_zod9.z.string().min(1).nullable(),
|
|
15255
15665
|
/** One entry per file, in output order. */
|
|
15256
|
-
outputs:
|
|
15666
|
+
outputs: import_zod9.z.array(CompanionOutputSchema).min(1)
|
|
15257
15667
|
}).strict();
|
|
15258
|
-
var CompanionV1Schema =
|
|
15259
|
-
version:
|
|
15260
|
-
basedOn:
|
|
15261
|
-
sha256:
|
|
15262
|
-
editor:
|
|
15263
|
-
protocol:
|
|
15264
|
-
savedAt:
|
|
15265
|
-
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()
|
|
15266
15676
|
}).strict();
|
|
15267
|
-
var HandEditCompanionSchema =
|
|
15677
|
+
var HandEditCompanionSchema = import_zod9.z.union([CompanionV2Schema, CompanionV1Schema]).transform(
|
|
15268
15678
|
(value) => value.version === 2 ? value : {
|
|
15269
15679
|
version: 2,
|
|
15270
15680
|
editor: value.editor,
|
|
@@ -15384,40 +15794,40 @@ function openInEditor(file, editor = process.env.PIXELKILN_EDITOR) {
|
|
|
15384
15794
|
}
|
|
15385
15795
|
|
|
15386
15796
|
// src/gallery/edit.ts
|
|
15387
|
-
var Base64 =
|
|
15388
|
-
var HandEditRequestSchema =
|
|
15389
|
-
|
|
15390
|
-
action:
|
|
15391
|
-
project:
|
|
15392
|
-
assetId:
|
|
15393
|
-
styleId:
|
|
15394
|
-
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}$/),
|
|
15395
15805
|
/** Also launch the author's editor on the file. */
|
|
15396
|
-
open:
|
|
15806
|
+
open: import_zod10.z.boolean().optional()
|
|
15397
15807
|
}).strict(),
|
|
15398
|
-
|
|
15399
|
-
action:
|
|
15400
|
-
project:
|
|
15401
|
-
assetId:
|
|
15402
|
-
styleId:
|
|
15403
|
-
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}$/)
|
|
15404
15814
|
}).strict(),
|
|
15405
15815
|
/** From the in-browser editor: the page holds the bytes, the server validates and writes. */
|
|
15406
|
-
|
|
15407
|
-
action:
|
|
15408
|
-
project:
|
|
15409
|
-
assetId:
|
|
15410
|
-
styleId:
|
|
15411
|
-
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}$/),
|
|
15412
15822
|
/** The flattened image; for a frame set, `frames` instead. */
|
|
15413
15823
|
png: Base64.min(1).optional(),
|
|
15414
15824
|
/** Every frame of a set, tagged with the role it was opened under (null for one added in the editor). */
|
|
15415
|
-
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(),
|
|
15416
15826
|
/** The editor's layered project file, kept beside the edit. */
|
|
15417
15827
|
pxo: Base64.optional(),
|
|
15418
15828
|
/** Editor identity from the bridge's ready message. */
|
|
15419
|
-
editor:
|
|
15420
|
-
protocol:
|
|
15829
|
+
editor: import_zod10.z.string().min(1).max(200),
|
|
15830
|
+
protocol: import_zod10.z.number().int().positive()
|
|
15421
15831
|
}).strict()
|
|
15422
15832
|
]);
|
|
15423
15833
|
function createGalleryEditHandler(opts) {
|
|
@@ -16751,27 +17161,27 @@ async function serveGallery(opts) {
|
|
|
16751
17161
|
|
|
16752
17162
|
// src/gallery/generate.ts
|
|
16753
17163
|
var import_node_crypto9 = require("crypto");
|
|
16754
|
-
var
|
|
16755
|
-
var GenerateRequestSchema =
|
|
16756
|
-
project:
|
|
16757
|
-
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),
|
|
16758
17168
|
/**
|
|
16759
17169
|
* Regenerate work that is up to date, as `gen --force` does, and let the
|
|
16760
17170
|
* fetch replace a locally modified or untracked file. With `restore`, put
|
|
16761
17171
|
* the recorded bytes back over a modified file.
|
|
16762
17172
|
*/
|
|
16763
|
-
force:
|
|
17173
|
+
force: import_zod11.z.boolean().optional(),
|
|
16764
17174
|
/** Advance in-flight, review, or selected work without submitting anything. */
|
|
16765
|
-
resume:
|
|
17175
|
+
resume: import_zod11.z.boolean().optional(),
|
|
16766
17176
|
/** Re-download downloaded outputs and replace files whose object changed upstream. */
|
|
16767
|
-
refresh:
|
|
17177
|
+
refresh: import_zod11.z.boolean().optional(),
|
|
16768
17178
|
/** Put recorded outputs back on disk from the cache or the provider, without generating. */
|
|
16769
|
-
restore:
|
|
17179
|
+
restore: import_zod11.z.boolean().optional(),
|
|
16770
17180
|
/**
|
|
16771
17181
|
* Bring a replaced generation back: 1-based position in the record's
|
|
16772
17182
|
* history (newest first) or an output hash prefix. One key at a time.
|
|
16773
17183
|
*/
|
|
16774
|
-
revert:
|
|
17184
|
+
revert: import_zod11.z.string().min(1).max(64).optional()
|
|
16775
17185
|
}).strict().refine((request) => [request.resume, request.refresh, request.restore, request.revert !== void 0].filter(Boolean).length <= 1, {
|
|
16776
17186
|
message: "resume, refresh, restore, and revert are exclusive"
|
|
16777
17187
|
}).refine((request) => request.revert === void 0 || request.keys.length === 1, { message: "revert takes one key" });
|