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/cli.js
CHANGED
|
@@ -68,7 +68,7 @@ function exitCodeFor(err) {
|
|
|
68
68
|
|
|
69
69
|
// src/cli/main.ts
|
|
70
70
|
import { existsSync as existsSync33 } from "fs";
|
|
71
|
-
import { readFile as
|
|
71
|
+
import { readFile as readFile31 } from "fs/promises";
|
|
72
72
|
|
|
73
73
|
// src/cli/args.ts
|
|
74
74
|
import path from "path";
|
|
@@ -157,6 +157,7 @@ var COMMANDS = [
|
|
|
157
157
|
"refine",
|
|
158
158
|
"recipe",
|
|
159
159
|
"workspace",
|
|
160
|
+
"estimate-skeleton",
|
|
160
161
|
"unzoom",
|
|
161
162
|
"font",
|
|
162
163
|
"help",
|
|
@@ -251,6 +252,10 @@ function parseArgs(argv) {
|
|
|
251
252
|
}
|
|
252
253
|
rest = rest.slice(1);
|
|
253
254
|
}
|
|
255
|
+
} else if (command === "estimate-skeleton") {
|
|
256
|
+
target = rest[0]?.startsWith("-") ? void 0 : rest[0];
|
|
257
|
+
if (target === void 0) throw new UsageError("estimate-skeleton needs an image path");
|
|
258
|
+
rest = rest.slice(1);
|
|
254
259
|
} else if (command === "refine") {
|
|
255
260
|
subcommand = rest[0]?.startsWith("-") || rest[0] === void 0 ? "run" : rest[0];
|
|
256
261
|
if (!REFINE_SUBCOMMANDS.includes(subcommand)) {
|
|
@@ -456,6 +461,11 @@ Commands
|
|
|
456
461
|
first. Local art is untouched.
|
|
457
462
|
tag Push manifest tags to the objects upstream (free).
|
|
458
463
|
balance Show the provider's remaining balance.
|
|
464
|
+
estimate-skeleton <image> [--out <file>]
|
|
465
|
+
PixelLab only: derive an 18-joint skeleton from an image, direct
|
|
466
|
+
and un-budgeted (like balance, not a generation). Prints the
|
|
467
|
+
keypoints JSON, or writes it with --out \u2014 the way to bootstrap
|
|
468
|
+
an animate-skeleton revision's keypointsFile.
|
|
459
469
|
status Summarise the lockfile.
|
|
460
470
|
edit Hand-edit an asset in your own editor: copies the generated PNG to
|
|
461
471
|
<outDir>/edits/, declares it as the asset's source, and opens it.
|
|
@@ -638,10 +648,10 @@ import { createReadStream } from "fs";
|
|
|
638
648
|
function sha256(data) {
|
|
639
649
|
return createHash("sha256").update(data).digest("hex");
|
|
640
650
|
}
|
|
641
|
-
async function sha256File(
|
|
651
|
+
async function sha256File(path48) {
|
|
642
652
|
return new Promise((resolve, reject) => {
|
|
643
653
|
const hash = createHash("sha256");
|
|
644
|
-
const stream = createReadStream(
|
|
654
|
+
const stream = createReadStream(path48);
|
|
645
655
|
stream.on("data", (chunk2) => hash.update(chunk2));
|
|
646
656
|
stream.on("error", reject);
|
|
647
657
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
@@ -679,6 +689,7 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
679
689
|
uiPieces: spec.uiPieces,
|
|
680
690
|
uiElements: spec.uiElements,
|
|
681
691
|
uiColorPalette: spec.uiColorPalette,
|
|
692
|
+
styleTraits: spec.styleTraits,
|
|
682
693
|
styleImages: styleImageHashes,
|
|
683
694
|
// A character family: the engine and rotations of a base, the parent's
|
|
684
695
|
// generated bytes for a state or animation (so a regenerated parent
|
|
@@ -755,7 +766,11 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
755
766
|
fps: spec.revision.fps,
|
|
756
767
|
lastFrameSha256: spec.revision.lastFrameSha256,
|
|
757
768
|
direction: spec.revision.direction,
|
|
758
|
-
enhancePrompt: spec.revision.enhancePrompt
|
|
769
|
+
enhancePrompt: spec.revision.enhancePrompt,
|
|
770
|
+
keypointsSha256: spec.revision.keypointsSha256,
|
|
771
|
+
skeletonTemplate: spec.revision.skeletonTemplate,
|
|
772
|
+
description: spec.revision.description,
|
|
773
|
+
engine: spec.revision.engine
|
|
759
774
|
} : void 0
|
|
760
775
|
})
|
|
761
776
|
);
|
|
@@ -773,7 +788,7 @@ import path2 from "path";
|
|
|
773
788
|
// src/types.ts
|
|
774
789
|
import { z } from "zod";
|
|
775
790
|
var MediaTypeSchema = z.enum(["image/png", "image/gif"]);
|
|
776
|
-
var GeneratorSchema = z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro", "uiAsset", "uiElement"]);
|
|
791
|
+
var GeneratorSchema = z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro", "uiAsset", "uiElement", "imageProFlash"]);
|
|
777
792
|
var GridConfidenceSchema = z.enum(["low", "medium", "high"]);
|
|
778
793
|
var RevisionModeSchema = z.enum([
|
|
779
794
|
"image-to-image",
|
|
@@ -783,6 +798,7 @@ var RevisionModeSchema = z.enum([
|
|
|
783
798
|
"correct-pixelart",
|
|
784
799
|
"animate",
|
|
785
800
|
"animate-pixminimax",
|
|
801
|
+
"animate-skeleton",
|
|
786
802
|
"interpolate",
|
|
787
803
|
"edit-animation"
|
|
788
804
|
]);
|
|
@@ -1100,8 +1116,46 @@ var RevisionSchema = z.object({
|
|
|
1100
1116
|
/** `animate-pixminimax` only: facing direction, used only alongside `enhancePrompt` to hold the sprite's facing. */
|
|
1101
1117
|
direction: CharacterDirectionSchema.optional(),
|
|
1102
1118
|
/** `animate`/`animate-pixminimax` only: let PixelLab expand the action into a fuller motion description first. */
|
|
1103
|
-
enhancePrompt: z.boolean().optional()
|
|
1119
|
+
enhancePrompt: z.boolean().optional(),
|
|
1120
|
+
/**
|
|
1121
|
+
* `animate-skeleton` only: manifest-relative path to a committed
|
|
1122
|
+
* `SkeletonSet` JSON file (see `src/skeleton.ts`) — the pose the parent
|
|
1123
|
+
* image is already in, plus 3-15 per-frame poses for the motion.
|
|
1124
|
+
* Authored via `pixelkiln estimate-skeleton`, then hand-tweaked; never
|
|
1125
|
+
* inline in the manifest, the same reasoning `mask`/`lastFrame` are
|
|
1126
|
+
* committed files rather than inline pixel data.
|
|
1127
|
+
*/
|
|
1128
|
+
keypointsFile: z.string().min(1).optional(),
|
|
1129
|
+
/**
|
|
1130
|
+
* `animate-skeleton` only: the body a joint's missing `depth` is taken
|
|
1131
|
+
* from. PixelLab's default is `mannequin`; free string like `character`'s
|
|
1132
|
+
* own `template` field, validated at the provider layer against the
|
|
1133
|
+
* same `mannequin`/`bear`/`cat`/`dog`/`horse`/`lion` vocabulary.
|
|
1134
|
+
*/
|
|
1135
|
+
skeletonTemplate: z.string().min(1).optional(),
|
|
1136
|
+
/**
|
|
1137
|
+
* `animate-skeleton` only: what the character *looks like*, a noun
|
|
1138
|
+
* phrase (colours, clothing, held items) — distinct from the asset's
|
|
1139
|
+
* own `prompt`, which this mode sends as the motion's short label
|
|
1140
|
+
* (PixelLab's `action`), the same `prompt`-as-motion convention
|
|
1141
|
+
* `animate`/`animate-pixminimax` already use.
|
|
1142
|
+
*/
|
|
1143
|
+
description: z.string().min(1).optional(),
|
|
1144
|
+
/**
|
|
1145
|
+
* `image-to-image`/`inpaint` only: which provider engine draws the
|
|
1146
|
+
* edit. `pro-flash` selects PixelLab's Pro Flash edit and inpaint tier
|
|
1147
|
+
* (`/edit-image-pro-flash`, `/inpaint-image-pro-flash`) instead of the
|
|
1148
|
+
* default Pro endpoints; omit it for the default.
|
|
1149
|
+
*/
|
|
1150
|
+
engine: z.enum(["pro-flash"]).optional()
|
|
1104
1151
|
}).strict().superRefine((revision, context) => {
|
|
1152
|
+
if (revision.engine !== void 0 && revision.mode !== "image-to-image" && revision.mode !== "inpaint") {
|
|
1153
|
+
context.addIssue({
|
|
1154
|
+
code: z.ZodIssueCode.custom,
|
|
1155
|
+
message: "engine applies to image-to-image and inpaint revisions only",
|
|
1156
|
+
path: ["engine"]
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1105
1159
|
if (revision.mode === "inpaint" && !revision.mask) {
|
|
1106
1160
|
context.addIssue({
|
|
1107
1161
|
code: z.ZodIssueCode.custom,
|
|
@@ -1177,18 +1231,41 @@ var RevisionSchema = z.object({
|
|
|
1177
1231
|
path: ["fps"]
|
|
1178
1232
|
});
|
|
1179
1233
|
}
|
|
1180
|
-
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax") {
|
|
1234
|
+
if (revision.direction !== void 0 && revision.mode !== "animate-pixminimax" && revision.mode !== "animate-skeleton") {
|
|
1235
|
+
context.addIssue({
|
|
1236
|
+
code: z.ZodIssueCode.custom,
|
|
1237
|
+
message: "direction applies to animate-pixminimax/animate-skeleton revisions only",
|
|
1238
|
+
path: ["direction"]
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
if (revision.mode === "animate-skeleton" && revision.direction === void 0) {
|
|
1181
1242
|
context.addIssue({
|
|
1182
1243
|
code: z.ZodIssueCode.custom,
|
|
1183
|
-
message: "
|
|
1244
|
+
message: "animate-skeleton revisions require a direction",
|
|
1184
1245
|
path: ["direction"]
|
|
1185
1246
|
});
|
|
1186
1247
|
}
|
|
1187
1248
|
if (revision.frames !== void 0 && revision.frames % 2 !== 0) {
|
|
1188
1249
|
context.addIssue({ code: z.ZodIssueCode.custom, message: "frames must be even", path: ["frames"] });
|
|
1189
1250
|
}
|
|
1251
|
+
if (revision.mode === "animate-skeleton" && !revision.keypointsFile) {
|
|
1252
|
+
context.addIssue({
|
|
1253
|
+
code: z.ZodIssueCode.custom,
|
|
1254
|
+
message: "animate-skeleton revisions require keypointsFile",
|
|
1255
|
+
path: ["keypointsFile"]
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
for (const field of ["keypointsFile", "skeletonTemplate", "description"]) {
|
|
1259
|
+
if (revision[field] !== void 0 && revision.mode !== "animate-skeleton") {
|
|
1260
|
+
context.addIssue({
|
|
1261
|
+
code: z.ZodIssueCode.custom,
|
|
1262
|
+
message: `${field} applies to animate-skeleton revisions only`,
|
|
1263
|
+
path: [field]
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1190
1267
|
});
|
|
1191
|
-
var FRAME_SET_REVISION_MODES = ["animate", "animate-pixminimax", "interpolate", "edit-animation"];
|
|
1268
|
+
var FRAME_SET_REVISION_MODES = ["animate", "animate-pixminimax", "animate-skeleton", "interpolate", "edit-animation"];
|
|
1192
1269
|
var MEMBER_SET_REVISION_MODES = ["reduce-colors", "correct-pixelart", "edit-animation"];
|
|
1193
1270
|
var StyleObjectSchema = z.object({
|
|
1194
1271
|
/** Generation backend for this style. Omit to inherit the manifest default. */
|
|
@@ -1390,8 +1467,8 @@ var StyleObjectSchema = z.object({
|
|
|
1390
1467
|
/** `character` only. Body template: `mannequin` (default), a quadruped (`bear`, `cat`, `dog`, `horse`, `lion`), or `custom` for `pro-flash`. */
|
|
1391
1468
|
template: z.string().min(1).optional(),
|
|
1392
1469
|
/**
|
|
1393
|
-
* `character`
|
|
1394
|
-
* the style image lends. Each defaults to true.
|
|
1470
|
+
* `character` `pro-flash` bases and `imageProFlash` styles, with a
|
|
1471
|
+
* style image: which traits the style image lends. Each defaults to true.
|
|
1395
1472
|
*/
|
|
1396
1473
|
styleTraits: z.object({
|
|
1397
1474
|
palette: z.boolean().optional(),
|
|
@@ -1820,11 +1897,17 @@ var LockEntrySchema = z.object({
|
|
|
1820
1897
|
paletteImageSha256: z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1821
1898
|
dithering: RevisionDitheringSchema.optional(),
|
|
1822
1899
|
ditheringStrength: z.number().min(0).max(10).optional(),
|
|
1823
|
-
|
|
1900
|
+
// 4-40 for animate/animate-pixminimax; animate-skeleton's own 3-15
|
|
1901
|
+
// range extends the floor down to 3, hence min(3) here rather than 4.
|
|
1902
|
+
frames: z.number().int().min(3).max(40).optional(),
|
|
1824
1903
|
fps: z.number().int().min(1).max(60).optional(),
|
|
1825
1904
|
lastFrameSha256: z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1826
1905
|
direction: CharacterDirectionSchema.optional(),
|
|
1827
|
-
enhancePrompt: z.boolean().optional()
|
|
1906
|
+
enhancePrompt: z.boolean().optional(),
|
|
1907
|
+
keypointsSha256: z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1908
|
+
skeletonTemplate: z.string().min(1).optional(),
|
|
1909
|
+
description: z.string().min(1).optional(),
|
|
1910
|
+
engine: z.enum(["pro-flash"]).optional()
|
|
1828
1911
|
}).strict().nullable().default(null),
|
|
1829
1912
|
/** For a mirror: the asset it flips and a hash over that asset's output hashes when this was made. */
|
|
1830
1913
|
mirror: z.object({
|
|
@@ -4976,11 +5059,12 @@ var ComfyUIProvider = class _ComfyUIProvider {
|
|
|
4976
5059
|
/**
|
|
4977
5060
|
* Everything else resolves generically to whatever the user's own
|
|
4978
5061
|
* workflow does with `bindings.sourceImage`. The frame-set modes
|
|
4979
|
-
* (`animate`, `animate-pixminimax`, `
|
|
4980
|
-
* the exception: they produce an ordered frame set,
|
|
4981
|
-
* revision path always writes a single output image
|
|
4982
|
-
* below) — a real structural gap, not a missing
|
|
4983
|
-
* rejected here rather than only failing once
|
|
5062
|
+
* (`animate`, `animate-pixminimax`, `animate-skeleton`, `interpolate`,
|
|
5063
|
+
* `edit-animation`) are the exception: they produce an ordered frame set,
|
|
5064
|
+
* and this adapter's revision path always writes a single output image
|
|
5065
|
+
* (see `submit`/`fetch` below) — a real structural gap, not a missing
|
|
5066
|
+
* binding, so they are rejected here rather than only failing once
|
|
5067
|
+
* `validate` runs.
|
|
4984
5068
|
*/
|
|
4985
5069
|
supportsRevision(mode2) {
|
|
4986
5070
|
return !FRAME_SET_REVISION_MODES.includes(mode2);
|
|
@@ -5036,6 +5120,11 @@ var ComfyUIProvider = class _ComfyUIProvider {
|
|
|
5036
5120
|
throw new Error("ComfyUI providerOptions.frames requires generator: frames");
|
|
5037
5121
|
}
|
|
5038
5122
|
if (spec.revision) {
|
|
5123
|
+
if (spec.revision.engine) {
|
|
5124
|
+
throw new Error(
|
|
5125
|
+
`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.`
|
|
5126
|
+
);
|
|
5127
|
+
}
|
|
5039
5128
|
if (spec.revision.sourceMembers) {
|
|
5040
5129
|
throw new Error(
|
|
5041
5130
|
`ComfyUI revisions read one source image; ${spec.revision.sourceAssetId} is a ${spec.revision.sourceMembers.length}-member set (directions or frames)`
|
|
@@ -5635,254 +5724,291 @@ import os from "os";
|
|
|
5635
5724
|
import path12 from "path";
|
|
5636
5725
|
|
|
5637
5726
|
// src/client.ts
|
|
5727
|
+
import { z as z3 } from "zod";
|
|
5728
|
+
|
|
5729
|
+
// src/skeleton.ts
|
|
5638
5730
|
import { z as z2 } from "zod";
|
|
5731
|
+
var SkeletonKeypointSchema = z2.object({
|
|
5732
|
+
label: z2.string().min(1),
|
|
5733
|
+
x: z2.number().min(0).max(1),
|
|
5734
|
+
y: z2.number().min(0).max(1),
|
|
5735
|
+
z_index: z2.number(),
|
|
5736
|
+
depth: z2.number().optional()
|
|
5737
|
+
}).strict();
|
|
5738
|
+
var SkeletonFrameSchema = z2.array(SkeletonKeypointSchema).length(18);
|
|
5739
|
+
var SkeletonSetSchema = z2.object({
|
|
5740
|
+
firstFrameKeypoints: SkeletonFrameSchema,
|
|
5741
|
+
frames: z2.array(SkeletonFrameSchema).min(3).max(15)
|
|
5742
|
+
}).strict();
|
|
5743
|
+
function parseSkeletonSet(json, file) {
|
|
5744
|
+
const result = SkeletonSetSchema.safeParse(json);
|
|
5745
|
+
if (!result.success) {
|
|
5746
|
+
const issues = result.error.issues.slice(0, 4).map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join("; ");
|
|
5747
|
+
throw new Error(`revision keypoints file ${file} does not match the expected shape: ${issues}`);
|
|
5748
|
+
}
|
|
5749
|
+
return result.data;
|
|
5750
|
+
}
|
|
5751
|
+
|
|
5752
|
+
// src/client.ts
|
|
5639
5753
|
var BASE = process.env.PIXELLAB_API_BASE ?? "https://api.pixellab.ai/v2";
|
|
5640
5754
|
var MAX_DOWNLOAD_BYTES = 64 * 1024 * 1024;
|
|
5641
|
-
var BalanceResponseSchema =
|
|
5642
|
-
credits:
|
|
5643
|
-
subscription:
|
|
5644
|
-
generations:
|
|
5645
|
-
total:
|
|
5646
|
-
plan:
|
|
5755
|
+
var BalanceResponseSchema = z3.object({
|
|
5756
|
+
credits: z3.object({ usd: z3.number() }).passthrough(),
|
|
5757
|
+
subscription: z3.object({
|
|
5758
|
+
generations: z3.number(),
|
|
5759
|
+
total: z3.number(),
|
|
5760
|
+
plan: z3.string().nullable().optional()
|
|
5647
5761
|
}).passthrough()
|
|
5648
5762
|
}).passthrough();
|
|
5649
|
-
var ObjectSubmitSchema =
|
|
5650
|
-
background_job_id:
|
|
5651
|
-
object_id:
|
|
5652
|
-
status:
|
|
5653
|
-
n_frames:
|
|
5763
|
+
var ObjectSubmitSchema = z3.object({
|
|
5764
|
+
background_job_id: z3.string().min(1),
|
|
5765
|
+
object_id: z3.string().min(1),
|
|
5766
|
+
status: z3.string().default("queued"),
|
|
5767
|
+
n_frames: z3.number().int().min(0)
|
|
5654
5768
|
}).passthrough();
|
|
5655
|
-
var MapSubmitSchema =
|
|
5656
|
-
background_job_id:
|
|
5657
|
-
object_id:
|
|
5658
|
-
status:
|
|
5769
|
+
var MapSubmitSchema = z3.object({
|
|
5770
|
+
background_job_id: z3.string().min(1),
|
|
5771
|
+
object_id: z3.string().min(1),
|
|
5772
|
+
status: z3.string().default("processing")
|
|
5659
5773
|
}).passthrough();
|
|
5660
|
-
var UsageSchema =
|
|
5661
|
-
type:
|
|
5662
|
-
usd:
|
|
5663
|
-
generations:
|
|
5774
|
+
var UsageSchema = z3.object({
|
|
5775
|
+
type: z3.string().optional(),
|
|
5776
|
+
usd: z3.number().nullable().optional(),
|
|
5777
|
+
generations: z3.number().nullable().optional()
|
|
5664
5778
|
}).passthrough().nullable().optional();
|
|
5665
|
-
var TilesSubmitSchema =
|
|
5666
|
-
tile_id:
|
|
5667
|
-
background_job_id:
|
|
5668
|
-
status:
|
|
5779
|
+
var TilesSubmitSchema = z3.object({
|
|
5780
|
+
tile_id: z3.string().min(1),
|
|
5781
|
+
background_job_id: z3.string().min(1),
|
|
5782
|
+
status: z3.literal("processing").default("processing")
|
|
5669
5783
|
}).passthrough();
|
|
5670
|
-
var TilesProSchema =
|
|
5671
|
-
storage_urls:
|
|
5672
|
-
kind:
|
|
5673
|
-
tile_rules:
|
|
5784
|
+
var TilesProSchema = z3.object({
|
|
5785
|
+
storage_urls: z3.record(z3.string()),
|
|
5786
|
+
kind: z3.string().nullable().default(null),
|
|
5787
|
+
tile_rules: z3.record(z3.unknown()).nullable().optional()
|
|
5674
5788
|
}).passthrough();
|
|
5675
|
-
var TilesetSubmitSchema =
|
|
5676
|
-
tileset_id:
|
|
5677
|
-
background_job_id:
|
|
5678
|
-
status:
|
|
5789
|
+
var TilesetSubmitSchema = z3.object({
|
|
5790
|
+
tileset_id: z3.string().min(1),
|
|
5791
|
+
background_job_id: z3.string().min(1),
|
|
5792
|
+
status: z3.literal("processing").default("processing")
|
|
5679
5793
|
}).passthrough();
|
|
5680
|
-
var TilesetTileSchema =
|
|
5681
|
-
id:
|
|
5682
|
-
name:
|
|
5683
|
-
image:
|
|
5684
|
-
corners:
|
|
5685
|
-
pattern_4x4:
|
|
5686
|
-
row_0:
|
|
5687
|
-
row_1:
|
|
5688
|
-
row_2:
|
|
5689
|
-
row_3:
|
|
5794
|
+
var TilesetTileSchema = z3.object({
|
|
5795
|
+
id: z3.string().min(1),
|
|
5796
|
+
name: z3.string(),
|
|
5797
|
+
image: z3.object({ base64: z3.string().min(1), format: z3.string().default("png") }).passthrough(),
|
|
5798
|
+
corners: z3.object({ NW: z3.string(), NE: z3.string(), SW: z3.string(), SE: z3.string() }).passthrough(),
|
|
5799
|
+
pattern_4x4: z3.object({
|
|
5800
|
+
row_0: z3.array(z3.number()),
|
|
5801
|
+
row_1: z3.array(z3.number()),
|
|
5802
|
+
row_2: z3.array(z3.number()),
|
|
5803
|
+
row_3: z3.array(z3.number())
|
|
5690
5804
|
}).passthrough()
|
|
5691
5805
|
}).passthrough();
|
|
5692
|
-
var TilesetGetSchema =
|
|
5693
|
-
tileset:
|
|
5694
|
-
total_tiles:
|
|
5695
|
-
tile_size:
|
|
5696
|
-
terrain_types:
|
|
5697
|
-
tiles:
|
|
5806
|
+
var TilesetGetSchema = z3.object({
|
|
5807
|
+
tileset: z3.object({
|
|
5808
|
+
total_tiles: z3.number().int().min(1),
|
|
5809
|
+
tile_size: z3.object({ width: z3.number().int().positive(), height: z3.number().int().positive() }).passthrough(),
|
|
5810
|
+
terrain_types: z3.array(z3.string()),
|
|
5811
|
+
tiles: z3.array(TilesetTileSchema).min(1)
|
|
5698
5812
|
}).passthrough(),
|
|
5699
5813
|
usage: UsageSchema
|
|
5700
5814
|
}).passthrough();
|
|
5701
|
-
var IsometricTileSubmitSchema =
|
|
5702
|
-
tile_id:
|
|
5703
|
-
background_job_id:
|
|
5704
|
-
status:
|
|
5815
|
+
var IsometricTileSubmitSchema = z3.object({
|
|
5816
|
+
tile_id: z3.string().min(1),
|
|
5817
|
+
background_job_id: z3.string().min(1),
|
|
5818
|
+
status: z3.literal("processing").default("processing")
|
|
5705
5819
|
}).passthrough();
|
|
5706
|
-
var IsometricTileGetSchema =
|
|
5707
|
-
image:
|
|
5820
|
+
var IsometricTileGetSchema = z3.object({
|
|
5821
|
+
image: z3.object({ base64: z3.string().min(1), format: z3.string().default("png") }).passthrough(),
|
|
5708
5822
|
usage: UsageSchema
|
|
5709
5823
|
}).passthrough();
|
|
5710
|
-
var UiAssetSubmitSchema =
|
|
5711
|
-
ui_asset_id:
|
|
5712
|
-
background_job_id:
|
|
5713
|
-
status:
|
|
5824
|
+
var UiAssetSubmitSchema = z3.object({
|
|
5825
|
+
ui_asset_id: z3.string().min(1),
|
|
5826
|
+
background_job_id: z3.string().min(1),
|
|
5827
|
+
status: z3.string().default("processing"),
|
|
5714
5828
|
usage: UsageSchema
|
|
5715
5829
|
}).passthrough();
|
|
5716
|
-
var UiAssetGetSchema =
|
|
5717
|
-
id:
|
|
5718
|
-
status:
|
|
5719
|
-
image_url:
|
|
5720
|
-
progress_percent:
|
|
5721
|
-
eta_seconds:
|
|
5830
|
+
var UiAssetGetSchema = z3.object({
|
|
5831
|
+
id: z3.string().min(1),
|
|
5832
|
+
status: z3.string().nullable().default(null),
|
|
5833
|
+
image_url: z3.string().nullable().optional(),
|
|
5834
|
+
progress_percent: z3.number().nullable().optional(),
|
|
5835
|
+
eta_seconds: z3.number().nullable().optional()
|
|
5722
5836
|
}).passthrough();
|
|
5723
|
-
var RevisionJobSubmitSchema =
|
|
5724
|
-
background_job_id:
|
|
5725
|
-
status:
|
|
5837
|
+
var RevisionJobSubmitSchema = z3.object({
|
|
5838
|
+
background_job_id: z3.string().min(1),
|
|
5839
|
+
status: z3.string().default("processing")
|
|
5726
5840
|
}).passthrough();
|
|
5727
|
-
var ObjectAnimationGroupSchema =
|
|
5728
|
-
animation_group_id:
|
|
5729
|
-
display_name:
|
|
5730
|
-
description:
|
|
5731
|
-
frame_count:
|
|
5732
|
-
directions:
|
|
5733
|
-
|
|
5734
|
-
direction:
|
|
5735
|
-
storage_urls:
|
|
5736
|
-
created_at:
|
|
5841
|
+
var ObjectAnimationGroupSchema = z3.object({
|
|
5842
|
+
animation_group_id: z3.string().min(1),
|
|
5843
|
+
display_name: z3.string().nullable().default(null),
|
|
5844
|
+
description: z3.string().default(""),
|
|
5845
|
+
frame_count: z3.number().int().default(0),
|
|
5846
|
+
directions: z3.array(
|
|
5847
|
+
z3.object({
|
|
5848
|
+
direction: z3.string(),
|
|
5849
|
+
storage_urls: z3.record(z3.unknown()).default({}),
|
|
5850
|
+
created_at: z3.string()
|
|
5737
5851
|
}).passthrough()
|
|
5738
5852
|
).default([])
|
|
5739
5853
|
}).passthrough();
|
|
5740
|
-
var PixelLabObjectSchema =
|
|
5741
|
-
id:
|
|
5742
|
-
name:
|
|
5743
|
-
state_name:
|
|
5744
|
-
prompt:
|
|
5745
|
-
size:
|
|
5746
|
-
directions:
|
|
5747
|
-
created_at:
|
|
5748
|
-
view:
|
|
5749
|
-
preview_url:
|
|
5750
|
-
rotation_urls:
|
|
5751
|
-
frame_urls:
|
|
5752
|
-
tags:
|
|
5753
|
-
status:
|
|
5754
|
-
progress_percent:
|
|
5755
|
-
eta_seconds:
|
|
5756
|
-
group_id:
|
|
5757
|
-
animations:
|
|
5854
|
+
var PixelLabObjectSchema = z3.object({
|
|
5855
|
+
id: z3.string().min(1),
|
|
5856
|
+
name: z3.string().nullable().default(null),
|
|
5857
|
+
state_name: z3.string().nullable().optional(),
|
|
5858
|
+
prompt: z3.string().default(""),
|
|
5859
|
+
size: z3.object({ width: z3.number().int().positive(), height: z3.number().int().positive() }),
|
|
5860
|
+
directions: z3.number().default(0),
|
|
5861
|
+
created_at: z3.string(),
|
|
5862
|
+
view: z3.string().nullable().default(null),
|
|
5863
|
+
preview_url: z3.string().nullable().optional(),
|
|
5864
|
+
rotation_urls: z3.record(z3.string().nullable()).nullable().optional(),
|
|
5865
|
+
frame_urls: z3.array(z3.string()).nullable().optional(),
|
|
5866
|
+
tags: z3.array(z3.string()).default([]),
|
|
5867
|
+
status: z3.string().nullable().default(null),
|
|
5868
|
+
progress_percent: z3.number().nullable().optional(),
|
|
5869
|
+
eta_seconds: z3.number().nullable().optional(),
|
|
5870
|
+
group_id: z3.string().nullable().optional(),
|
|
5871
|
+
animations: z3.array(ObjectAnimationGroupSchema).default([])
|
|
5758
5872
|
}).passthrough();
|
|
5759
|
-
var MapObjectSchema =
|
|
5760
|
-
object_id:
|
|
5761
|
-
status:
|
|
5762
|
-
description:
|
|
5763
|
-
width:
|
|
5764
|
-
height:
|
|
5765
|
-
download_url:
|
|
5873
|
+
var MapObjectSchema = z3.object({
|
|
5874
|
+
object_id: z3.string().min(1),
|
|
5875
|
+
status: z3.string(),
|
|
5876
|
+
description: z3.string().nullable().default(null),
|
|
5877
|
+
width: z3.number().nullable().default(null),
|
|
5878
|
+
height: z3.number().nullable().default(null),
|
|
5879
|
+
download_url: z3.string().nullable().default(null)
|
|
5766
5880
|
}).passthrough();
|
|
5767
|
-
var ObjectListSchema =
|
|
5768
|
-
var PixfluxResponseSchema =
|
|
5769
|
-
var ReduceColorsResponseSchema =
|
|
5770
|
-
images:
|
|
5771
|
-
palette:
|
|
5772
|
-
n_colors:
|
|
5773
|
-
usage:
|
|
5881
|
+
var ObjectListSchema = z3.object({ objects: z3.array(PixelLabObjectSchema), total: z3.number().int().min(0) }).passthrough();
|
|
5882
|
+
var PixfluxResponseSchema = z3.object({ image: z3.object({ base64: z3.string().min(1) }).passthrough(), usage: z3.unknown().optional() }).passthrough();
|
|
5883
|
+
var ReduceColorsResponseSchema = z3.object({
|
|
5884
|
+
images: z3.array(z3.object({ base64: z3.string().min(1) }).passthrough()).min(1),
|
|
5885
|
+
palette: z3.object({ base64: z3.string().min(1) }).passthrough(),
|
|
5886
|
+
n_colors: z3.number().int(),
|
|
5887
|
+
usage: z3.unknown().optional()
|
|
5774
5888
|
}).passthrough();
|
|
5775
|
-
var CorrectPixelartResponseSchema =
|
|
5776
|
-
images:
|
|
5777
|
-
usage:
|
|
5889
|
+
var CorrectPixelartResponseSchema = z3.object({
|
|
5890
|
+
images: z3.array(z3.object({ base64: z3.string().min(1) }).passthrough()).min(1),
|
|
5891
|
+
usage: z3.unknown().optional()
|
|
5778
5892
|
}).passthrough();
|
|
5779
|
-
var
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5893
|
+
var ProFlashImageSubmitSchema = z3.object({
|
|
5894
|
+
background_job_id: z3.string().min(1),
|
|
5895
|
+
image_id: z3.string().min(1),
|
|
5896
|
+
source_image_id: z3.string().min(1),
|
|
5897
|
+
status: z3.string().default("processing"),
|
|
5898
|
+
estimated_generations: z3.number().nullable().optional(),
|
|
5899
|
+
usage: z3.unknown().optional()
|
|
5785
5900
|
}).passthrough();
|
|
5786
|
-
var
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
usage: z2.unknown().optional()
|
|
5901
|
+
var UnzoomResponseSchema = z3.object({
|
|
5902
|
+
image: z3.object({ base64: z3.string().min(1) }).passthrough(),
|
|
5903
|
+
original_size: z3.object({ width: z3.number().int(), height: z3.number().int() }).passthrough(),
|
|
5904
|
+
unzoomed_size: z3.object({ width: z3.number().int(), height: z3.number().int() }).passthrough(),
|
|
5905
|
+
zoom_factor_detected: z3.number(),
|
|
5906
|
+
usage: z3.unknown().optional()
|
|
5793
5907
|
}).passthrough();
|
|
5794
|
-
var
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5908
|
+
var FontJobSchema = z3.object({
|
|
5909
|
+
job_id: z3.string().min(1),
|
|
5910
|
+
status: z3.string(),
|
|
5911
|
+
glyph_px: z3.number().int().nullable().optional(),
|
|
5912
|
+
download_atlas_url: z3.string().nullable().optional(),
|
|
5913
|
+
download_ttf_url: z3.string().nullable().optional(),
|
|
5914
|
+
usage: z3.unknown().optional()
|
|
5915
|
+
}).passthrough();
|
|
5916
|
+
var SelectFramesSchema = z3.object({ created_object_ids: z3.array(z3.string()) }).passthrough();
|
|
5917
|
+
var EstimateSkeletonResponseSchema = z3.object({
|
|
5918
|
+
keypoints: z3.array(SkeletonKeypointSchema).length(18),
|
|
5919
|
+
usage: z3.unknown().optional()
|
|
5920
|
+
}).passthrough();
|
|
5921
|
+
var CharacterSubmitSchema = z3.object({
|
|
5922
|
+
background_job_id: z3.string().min(1),
|
|
5923
|
+
character_id: z3.string().min(1),
|
|
5924
|
+
status: z3.string().default("processing"),
|
|
5799
5925
|
usage: UsageSchema
|
|
5800
5926
|
}).passthrough();
|
|
5801
|
-
var AnimateSubmitSchema =
|
|
5802
|
-
background_job_ids:
|
|
5803
|
-
directions:
|
|
5804
|
-
status:
|
|
5927
|
+
var AnimateSubmitSchema = z3.object({
|
|
5928
|
+
background_job_ids: z3.array(z3.string()),
|
|
5929
|
+
directions: z3.array(z3.string()),
|
|
5930
|
+
status: z3.string().default("processing"),
|
|
5805
5931
|
usage: UsageSchema
|
|
5806
5932
|
}).passthrough();
|
|
5807
|
-
var ObjectProSubmitSchema =
|
|
5808
|
-
object_id:
|
|
5809
|
-
background_job_id:
|
|
5810
|
-
status:
|
|
5933
|
+
var ObjectProSubmitSchema = z3.object({
|
|
5934
|
+
object_id: z3.string().min(1),
|
|
5935
|
+
background_job_id: z3.string().min(1),
|
|
5936
|
+
status: z3.string().default("processing"),
|
|
5811
5937
|
usage: UsageSchema
|
|
5812
5938
|
}).passthrough();
|
|
5813
|
-
var DirectionSubmissionSchema =
|
|
5814
|
-
direction:
|
|
5815
|
-
status:
|
|
5816
|
-
background_job_id:
|
|
5817
|
-
animation_id:
|
|
5939
|
+
var DirectionSubmissionSchema = z3.object({
|
|
5940
|
+
direction: z3.string(),
|
|
5941
|
+
status: z3.string(),
|
|
5942
|
+
background_job_id: z3.string().nullable().default(null),
|
|
5943
|
+
animation_id: z3.string().nullable().default(null)
|
|
5818
5944
|
}).passthrough();
|
|
5819
|
-
var AnimateObjectSubmitSchema =
|
|
5820
|
-
animation_group_id:
|
|
5821
|
-
object_id:
|
|
5822
|
-
mode:
|
|
5823
|
-
frame_count:
|
|
5824
|
-
display_name:
|
|
5825
|
-
description:
|
|
5826
|
-
submissions:
|
|
5945
|
+
var AnimateObjectSubmitSchema = z3.object({
|
|
5946
|
+
animation_group_id: z3.string().min(1),
|
|
5947
|
+
object_id: z3.string().min(1),
|
|
5948
|
+
mode: z3.string(),
|
|
5949
|
+
frame_count: z3.number().int(),
|
|
5950
|
+
display_name: z3.string().nullable().default(null),
|
|
5951
|
+
description: z3.string().default(""),
|
|
5952
|
+
submissions: z3.array(DirectionSubmissionSchema),
|
|
5827
5953
|
usage: UsageSchema
|
|
5828
5954
|
}).passthrough();
|
|
5829
|
-
var PortraitSubmitSchema =
|
|
5830
|
-
background_job_id:
|
|
5831
|
-
status:
|
|
5955
|
+
var PortraitSubmitSchema = z3.object({
|
|
5956
|
+
background_job_id: z3.string().min(1),
|
|
5957
|
+
status: z3.string().default("processing"),
|
|
5832
5958
|
usage: UsageSchema
|
|
5833
5959
|
}).passthrough();
|
|
5834
|
-
var PortraitJobSchema =
|
|
5835
|
-
status:
|
|
5836
|
-
download_url:
|
|
5837
|
-
width:
|
|
5838
|
-
height:
|
|
5960
|
+
var PortraitJobSchema = z3.object({
|
|
5961
|
+
status: z3.string(),
|
|
5962
|
+
download_url: z3.string().nullable().optional(),
|
|
5963
|
+
width: z3.number().int().nullable().optional(),
|
|
5964
|
+
height: z3.number().int().nullable().optional()
|
|
5839
5965
|
}).passthrough();
|
|
5840
|
-
var SetPortraitSchema =
|
|
5841
|
-
character_id:
|
|
5842
|
-
size:
|
|
5843
|
-
url:
|
|
5966
|
+
var SetPortraitSchema = z3.object({
|
|
5967
|
+
character_id: z3.string().min(1),
|
|
5968
|
+
size: z3.number().int().positive(),
|
|
5969
|
+
url: z3.string().min(1),
|
|
5844
5970
|
usage: UsageSchema
|
|
5845
5971
|
}).passthrough();
|
|
5846
|
-
var TransferOutfitSubmitSchema =
|
|
5847
|
-
background_job_id:
|
|
5848
|
-
status:
|
|
5972
|
+
var TransferOutfitSubmitSchema = z3.object({
|
|
5973
|
+
background_job_id: z3.string().min(1),
|
|
5974
|
+
status: z3.string().default("processing"),
|
|
5849
5975
|
usage: UsageSchema
|
|
5850
5976
|
}).passthrough();
|
|
5851
|
-
var CharacterAnimationDirectionSchema =
|
|
5852
|
-
direction:
|
|
5853
|
-
frame_count:
|
|
5854
|
-
frames:
|
|
5977
|
+
var CharacterAnimationDirectionSchema = z3.object({
|
|
5978
|
+
direction: z3.string(),
|
|
5979
|
+
frame_count: z3.number().int().min(0),
|
|
5980
|
+
frames: z3.array(z3.string())
|
|
5855
5981
|
}).passthrough();
|
|
5856
|
-
var CharacterAnimationSchema2 =
|
|
5857
|
-
animation_type:
|
|
5858
|
-
display_name:
|
|
5859
|
-
animation_group_id:
|
|
5860
|
-
directions:
|
|
5982
|
+
var CharacterAnimationSchema2 = z3.object({
|
|
5983
|
+
animation_type: z3.string(),
|
|
5984
|
+
display_name: z3.string().nullable().optional(),
|
|
5985
|
+
animation_group_id: z3.string().nullable().optional(),
|
|
5986
|
+
directions: z3.array(CharacterAnimationDirectionSchema)
|
|
5861
5987
|
}).passthrough();
|
|
5862
|
-
var CharacterSchema =
|
|
5863
|
-
id:
|
|
5864
|
-
name:
|
|
5865
|
-
state_name:
|
|
5866
|
-
prompt:
|
|
5867
|
-
size:
|
|
5868
|
-
directions:
|
|
5869
|
-
created_at:
|
|
5870
|
-
updated_at:
|
|
5871
|
-
animation_count:
|
|
5872
|
-
template_id:
|
|
5873
|
-
view:
|
|
5874
|
-
status:
|
|
5875
|
-
rotation_urls:
|
|
5876
|
-
tags:
|
|
5877
|
-
group_id:
|
|
5878
|
-
animations:
|
|
5879
|
-
preview_url:
|
|
5988
|
+
var CharacterSchema = z3.object({
|
|
5989
|
+
id: z3.string().min(1),
|
|
5990
|
+
name: z3.string().default(""),
|
|
5991
|
+
state_name: z3.string().nullable().optional(),
|
|
5992
|
+
prompt: z3.string().default(""),
|
|
5993
|
+
size: z3.object({ width: z3.number().int().positive(), height: z3.number().int().positive() }),
|
|
5994
|
+
directions: z3.number().int(),
|
|
5995
|
+
created_at: z3.string(),
|
|
5996
|
+
updated_at: z3.string().nullable().optional(),
|
|
5997
|
+
animation_count: z3.number().int().default(0),
|
|
5998
|
+
template_id: z3.string().default("mannequin"),
|
|
5999
|
+
view: z3.string().nullable().optional(),
|
|
6000
|
+
status: z3.string().default("completed"),
|
|
6001
|
+
rotation_urls: z3.record(z3.string().nullable()).nullable().optional(),
|
|
6002
|
+
tags: z3.array(z3.string()).default([]),
|
|
6003
|
+
group_id: z3.string().nullable().optional(),
|
|
6004
|
+
animations: z3.array(CharacterAnimationSchema2).default([]),
|
|
6005
|
+
preview_url: z3.string().nullable().optional()
|
|
5880
6006
|
}).passthrough();
|
|
5881
|
-
var CharacterListSchema =
|
|
5882
|
-
var BackgroundJobSchema =
|
|
5883
|
-
id:
|
|
5884
|
-
status:
|
|
5885
|
-
last_response:
|
|
6007
|
+
var CharacterListSchema = z3.object({ characters: z3.array(CharacterSchema), total: z3.number().int().min(0) }).passthrough();
|
|
6008
|
+
var BackgroundJobSchema = z3.object({
|
|
6009
|
+
id: z3.string(),
|
|
6010
|
+
status: z3.string(),
|
|
6011
|
+
last_response: z3.record(z3.unknown()).nullable().optional(),
|
|
5886
6012
|
/**
|
|
5887
6013
|
* The billed amount, confirmed live for a `map` object and a standard
|
|
5888
6014
|
* character base (docs/ENDPOINTS.md, "Limits and billing"); duplicated at
|
|
@@ -5890,7 +6016,7 @@ var BackgroundJobSchema = z2.object({
|
|
|
5890
6016
|
*/
|
|
5891
6017
|
usage: UsageSchema
|
|
5892
6018
|
}).passthrough();
|
|
5893
|
-
var DeleteAnimationsSchema =
|
|
6019
|
+
var DeleteAnimationsSchema = z3.object({ success: z3.boolean(), deleted_count: z3.number().int().default(0), error: z3.string().nullable().optional() }).passthrough();
|
|
5894
6020
|
function validateResponse(schema, raw, operation) {
|
|
5895
6021
|
const parsed = schema.safeParse(raw);
|
|
5896
6022
|
if (parsed.success) return parsed.data;
|
|
@@ -5936,9 +6062,9 @@ var PixelLabClient = class {
|
|
|
5936
6062
|
apiKey;
|
|
5937
6063
|
http;
|
|
5938
6064
|
/** Retries transport failures, 429, and 5xx; see http.ts for the policy. */
|
|
5939
|
-
async request(
|
|
6065
|
+
async request(path48, init) {
|
|
5940
6066
|
const auth = this.apiKey.startsWith("Bearer ") ? this.apiKey : `Bearer ${this.apiKey}`;
|
|
5941
|
-
const res = await this.http(`${BASE}${
|
|
6067
|
+
const res = await this.http(`${BASE}${path48}`, {
|
|
5942
6068
|
...init,
|
|
5943
6069
|
headers: {
|
|
5944
6070
|
Authorization: auth,
|
|
@@ -5948,13 +6074,13 @@ var PixelLabClient = class {
|
|
|
5948
6074
|
});
|
|
5949
6075
|
const text = await res.text();
|
|
5950
6076
|
if (!res.ok) {
|
|
5951
|
-
throw new PixelLabError(`${init?.method ?? "GET"} ${
|
|
6077
|
+
throw new PixelLabError(`${init?.method ?? "GET"} ${path48} \u2192 ${res.status}`, res.status, text);
|
|
5952
6078
|
}
|
|
5953
6079
|
if (!text) return {};
|
|
5954
6080
|
try {
|
|
5955
6081
|
return JSON.parse(text);
|
|
5956
6082
|
} catch {
|
|
5957
|
-
throw new Error(`${init?.method ?? "GET"} ${
|
|
6083
|
+
throw new Error(`${init?.method ?? "GET"} ${path48} returned invalid JSON`);
|
|
5958
6084
|
}
|
|
5959
6085
|
}
|
|
5960
6086
|
async balance() {
|
|
@@ -6216,7 +6342,7 @@ var PixelLabClient = class {
|
|
|
6216
6342
|
const body = {
|
|
6217
6343
|
description: args.description,
|
|
6218
6344
|
n_directions: args.directions,
|
|
6219
|
-
...args.reference ? { first_frame: encode(args.reference) } : { image_size: { width: args.size, height: args.size } },
|
|
6345
|
+
...args.sourceImageId ? { source_image_id: args.sourceImageId } : args.reference ? { first_frame: encode(args.reference) } : { image_size: { width: args.size, height: args.size } },
|
|
6220
6346
|
...args.view ? { view: args.view } : {},
|
|
6221
6347
|
...args.seed != null ? { seed: args.seed } : {},
|
|
6222
6348
|
...args.styleReference && args.styleReferenceSize ? {
|
|
@@ -6340,10 +6466,10 @@ var PixelLabClient = class {
|
|
|
6340
6466
|
const palette = args.paletteSwatchBase64 ? { color_image: { type: "base64", base64: args.paletteSwatchBase64, format: "png" }, force_colors: true } : {};
|
|
6341
6467
|
const encode = (image) => ({ type: "base64", base64: image.base64, format: image.format });
|
|
6342
6468
|
const south = args.reference?.south;
|
|
6343
|
-
let
|
|
6469
|
+
let path48;
|
|
6344
6470
|
let body;
|
|
6345
6471
|
if (args.mode === "v3") {
|
|
6346
|
-
|
|
6472
|
+
path48 = "/create-character-v3";
|
|
6347
6473
|
body = {
|
|
6348
6474
|
description: args.description,
|
|
6349
6475
|
image_size: imageSize,
|
|
@@ -6357,14 +6483,15 @@ var PixelLabClient = class {
|
|
|
6357
6483
|
...args.enhancePrompt ? { enhance_prompt: true } : {}
|
|
6358
6484
|
};
|
|
6359
6485
|
} else if (args.mode === "pro-flash") {
|
|
6360
|
-
|
|
6486
|
+
path48 = "/create-character-pro-flash";
|
|
6361
6487
|
const traits = args.styleTraits;
|
|
6362
6488
|
body = {
|
|
6363
6489
|
description: args.description,
|
|
6364
6490
|
template_id: args.template,
|
|
6365
6491
|
n_directions: 8,
|
|
6366
|
-
// The author's sprite sets the canvas; a size only applies to text
|
|
6367
|
-
|
|
6492
|
+
// The author's sprite sets the canvas; a size only applies to text
|
|
6493
|
+
// creation. An owned copy of the same sprite is referenced by id.
|
|
6494
|
+
...args.sourceImageId ? { source_image_id: args.sourceImageId } : south ? { first_frame: encode(south) } : { image_size: imageSize },
|
|
6368
6495
|
...args.view ? { view: args.view } : {},
|
|
6369
6496
|
...args.seed != null ? { seed: args.seed } : {},
|
|
6370
6497
|
...args.styleReference && args.styleReferenceSize ? {
|
|
@@ -6380,7 +6507,7 @@ var PixelLabClient = class {
|
|
|
6380
6507
|
} : {}
|
|
6381
6508
|
};
|
|
6382
6509
|
} else if (args.mode === "pro") {
|
|
6383
|
-
|
|
6510
|
+
path48 = "/create-character-pro";
|
|
6384
6511
|
body = {
|
|
6385
6512
|
description: args.description,
|
|
6386
6513
|
image_size: imageSize,
|
|
@@ -6394,7 +6521,7 @@ var PixelLabClient = class {
|
|
|
6394
6521
|
...!south && args.styleCharacterId ? { style_character_id: args.styleCharacterId } : {}
|
|
6395
6522
|
};
|
|
6396
6523
|
} else {
|
|
6397
|
-
|
|
6524
|
+
path48 = args.directions === 4 ? "/create-character-with-4-directions" : "/create-character-with-8-directions";
|
|
6398
6525
|
body = {
|
|
6399
6526
|
description: args.description,
|
|
6400
6527
|
image_size: imageSize,
|
|
@@ -6411,8 +6538,8 @@ var PixelLabClient = class {
|
|
|
6411
6538
|
...palette
|
|
6412
6539
|
};
|
|
6413
6540
|
}
|
|
6414
|
-
const raw = await this.request(
|
|
6415
|
-
return validateResponse(CharacterSubmitSchema, raw,
|
|
6541
|
+
const raw = await this.request(path48, { method: "POST", body: JSON.stringify(body) });
|
|
6542
|
+
return validateResponse(CharacterSubmitSchema, raw, path48.slice(1));
|
|
6416
6543
|
}
|
|
6417
6544
|
/** A text edit of an existing character, applied to every direction and stored as a sibling. */
|
|
6418
6545
|
async createCharacterState(args) {
|
|
@@ -6636,6 +6763,66 @@ var PixelLabClient = class {
|
|
|
6636
6763
|
"generate-image-v2"
|
|
6637
6764
|
);
|
|
6638
6765
|
}
|
|
6766
|
+
/**
|
|
6767
|
+
* `/create-image-pro-flash`: one native pixel-art image from a
|
|
6768
|
+
* description, optionally styled after a style image with per-trait
|
|
6769
|
+
* toggles, on the same Pro Flash model `character`/`objectPro` use for
|
|
6770
|
+
* their `pro-flash` engine. Sizes run 16 to 256 per side in multiples of 4.
|
|
6771
|
+
* A plain background job; `pollRevision`'s generic reader takes the
|
|
6772
|
+
* finished image. The response's `source_image_id` is what a Pro Flash
|
|
6773
|
+
* character or object can reuse instead of an upload.
|
|
6774
|
+
*/
|
|
6775
|
+
async createImageProFlash(args) {
|
|
6776
|
+
const body = {
|
|
6777
|
+
description: args.description,
|
|
6778
|
+
image_size: { width: args.width, height: args.height }
|
|
6779
|
+
};
|
|
6780
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
6781
|
+
if (args.seed != null) body.seed = args.seed;
|
|
6782
|
+
if (args.styleImage) {
|
|
6783
|
+
body.style_image = { image: args.styleImage.image, size: { width: args.styleImage.width, height: args.styleImage.height } };
|
|
6784
|
+
const traits = args.styleTraits;
|
|
6785
|
+
if (traits) {
|
|
6786
|
+
body.style_options = {
|
|
6787
|
+
...traits.palette !== void 0 ? { color_palette: traits.palette } : {},
|
|
6788
|
+
...traits.outline !== void 0 ? { outline: traits.outline } : {},
|
|
6789
|
+
...traits.detail !== void 0 ? { detail: traits.detail } : {},
|
|
6790
|
+
...traits.shading !== void 0 ? { shading: traits.shading } : {}
|
|
6791
|
+
};
|
|
6792
|
+
}
|
|
6793
|
+
}
|
|
6794
|
+
return validateResponse(
|
|
6795
|
+
ProFlashImageSubmitSchema,
|
|
6796
|
+
await this.request("/create-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
6797
|
+
"create-image-pro-flash"
|
|
6798
|
+
);
|
|
6799
|
+
}
|
|
6800
|
+
/** `/edit-image-pro-flash`, text method: edit one image at its own size. The canvas never grows or resizes. */
|
|
6801
|
+
async editImageProFlash(args) {
|
|
6802
|
+
const body = { image: args.image, method: "text", description: args.description };
|
|
6803
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
6804
|
+
if (args.seed != null) body.seed = args.seed;
|
|
6805
|
+
return validateResponse(
|
|
6806
|
+
ProFlashImageSubmitSchema,
|
|
6807
|
+
await this.request("/edit-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
6808
|
+
"edit-image-pro-flash"
|
|
6809
|
+
);
|
|
6810
|
+
}
|
|
6811
|
+
/**
|
|
6812
|
+
* `/inpaint-image-pro-flash`: replace only the white pixels of a same-size
|
|
6813
|
+
* black/white mask, keeping everything else exactly. `Modify current
|
|
6814
|
+
* layer` (the endpoint's default) returns the full composite.
|
|
6815
|
+
*/
|
|
6816
|
+
async inpaintImageProFlash(args) {
|
|
6817
|
+
const body = { image: args.image, mask_image: args.maskImage, description: args.description };
|
|
6818
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
6819
|
+
if (args.seed != null) body.seed = args.seed;
|
|
6820
|
+
return validateResponse(
|
|
6821
|
+
ProFlashImageSubmitSchema,
|
|
6822
|
+
await this.request("/inpaint-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
6823
|
+
"inpaint-image-pro-flash"
|
|
6824
|
+
);
|
|
6825
|
+
}
|
|
6639
6826
|
/**
|
|
6640
6827
|
* `/generate-ui-v2` ("Generate UI (Pro)"): one UI element (a button, a
|
|
6641
6828
|
* health bar, an inventory slot, a dialogue box) from a description,
|
|
@@ -6860,6 +7047,61 @@ var PixelLabClient = class {
|
|
|
6860
7047
|
"animate-pixminimax"
|
|
6861
7048
|
);
|
|
6862
7049
|
}
|
|
7050
|
+
/**
|
|
7051
|
+
* `/animate-with-skeleton-v3`, beta (tier 1 subscription or higher): poses
|
|
7052
|
+
* one reference image frame-by-frame from a supplied skeleton per frame,
|
|
7053
|
+
* rather than a text motion description. Confirmed against the live
|
|
7054
|
+
* `animate_with_skeleton_v3` MCP tool schema (the same authoritative
|
|
7055
|
+
* source this codebase already treats as ground truth for the
|
|
7056
|
+
* character/object family) — `action`/`description` are both real,
|
|
7057
|
+
* optional wire fields, contrary to an initial guess that this endpoint
|
|
7058
|
+
* took no text input at all; `direction`/`keypoints`/`firstFrameKeypoints`
|
|
7059
|
+
* are required. The example keypoint from that same tool schema,
|
|
7060
|
+
* `{"label": "RIGHT KNEE", "x": 0.52, "y": 0.71, "z_index": 9}`, is what
|
|
7061
|
+
* `SkeletonKeypointSchema` (`src/skeleton.ts`) models. Same
|
|
7062
|
+
* unverified-completed-shape caveat as `animateWithTextV3`/
|
|
7063
|
+
* `animatePixminimax` above — this endpoint has never been called against
|
|
7064
|
+
* a live account by this codebase.
|
|
7065
|
+
*/
|
|
7066
|
+
async animateWithSkeletonV3(args) {
|
|
7067
|
+
const body = {
|
|
7068
|
+
first_frame: args.firstFrame,
|
|
7069
|
+
first_frame_keypoints: args.firstFrameKeypoints,
|
|
7070
|
+
keypoints: args.keypoints,
|
|
7071
|
+
direction: args.direction
|
|
7072
|
+
};
|
|
7073
|
+
if (args.templateId) body.template_id = args.templateId;
|
|
7074
|
+
if (args.action) body.action = args.action;
|
|
7075
|
+
if (args.description) body.description = args.description;
|
|
7076
|
+
if (args.seed != null) body.seed = args.seed;
|
|
7077
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
7078
|
+
return validateResponse(
|
|
7079
|
+
RevisionJobSubmitSchema,
|
|
7080
|
+
await this.request("/animate-with-skeleton-v3", { method: "POST", body: JSON.stringify(body) }),
|
|
7081
|
+
"animate-with-skeleton-v3"
|
|
7082
|
+
);
|
|
7083
|
+
}
|
|
7084
|
+
/**
|
|
7085
|
+
* `/estimate-skeleton`: auto-derives a reference image's own 18-joint
|
|
7086
|
+
* keypoints, directly usable as `animateWithSkeletonV3`'s
|
|
7087
|
+
* `firstFrameKeypoints` (or, run against a candidate pose image, as one
|
|
7088
|
+
* entry of its `keypoints` sequence). Not called anywhere in this
|
|
7089
|
+
* codebase's own submit/poll pipeline — deliberately kept outside it (see
|
|
7090
|
+
* `runEstimateSkeleton` in `src/cli/commands`) so the only PixelLab
|
|
7091
|
+
* endpoint composed into `animate-with-skeleton-v3`'s submission is that
|
|
7092
|
+
* one endpoint itself, not two unverified calls chained together.
|
|
7093
|
+
* Synchronous per this endpoint's own framing; unverified against a live
|
|
7094
|
+
* account (see `EstimateSkeletonResponseSchema`'s own caveat).
|
|
7095
|
+
*/
|
|
7096
|
+
async estimateSkeleton(args) {
|
|
7097
|
+
const body = { image: args.image };
|
|
7098
|
+
const res = validateResponse(
|
|
7099
|
+
EstimateSkeletonResponseSchema,
|
|
7100
|
+
await this.request("/estimate-skeleton", { method: "POST", body: JSON.stringify(body) }),
|
|
7101
|
+
"estimate-skeleton"
|
|
7102
|
+
);
|
|
7103
|
+
return { keypoints: res.keypoints, usage: res.usage };
|
|
7104
|
+
}
|
|
6863
7105
|
async getBackgroundJob(jobId) {
|
|
6864
7106
|
const raw = await this.request(`/background-jobs/${encodeURIComponent(jobId)}`);
|
|
6865
7107
|
return validateResponse(BackgroundJobSchema, raw, "background-jobs/{id}");
|
|
@@ -6961,8 +7203,11 @@ function proFlashCharacterCost(width, height, fromReference) {
|
|
|
6961
7203
|
const side = Math.max(32, Math.ceil(Math.max(width, height) / 4) * 4);
|
|
6962
7204
|
const rotations = Math.max(1, Math.ceil(side * side * 8 / 65536));
|
|
6963
7205
|
if (fromReference) return rotations;
|
|
6964
|
-
|
|
6965
|
-
|
|
7206
|
+
return proFlashImageCost(side, side) + rotations;
|
|
7207
|
+
}
|
|
7208
|
+
function proFlashImageCost(width, height) {
|
|
7209
|
+
const side = Math.max(width, height);
|
|
7210
|
+
return side <= 96 ? 5 : side <= 208 ? 6 : 9;
|
|
6966
7211
|
}
|
|
6967
7212
|
function characterAnimationName(spec) {
|
|
6968
7213
|
return `pixelkiln:${spec.styleId}/${spec.assetId}`;
|
|
@@ -6990,6 +7235,18 @@ function objectProCost(spec) {
|
|
|
6990
7235
|
const south = object.reference;
|
|
6991
7236
|
return south ? proFlashObjectCost(south.width, south.height, object.directions, true) : proFlashObjectCost(spec.width, spec.height, object.directions, false);
|
|
6992
7237
|
}
|
|
7238
|
+
function animateSkeletonCost(frames) {
|
|
7239
|
+
const anchors = [[3, 2], [8, 3], [15, 4]];
|
|
7240
|
+
for (let i = 0; i < anchors.length - 1; i++) {
|
|
7241
|
+
const [lowFrames, lowCost] = anchors[i];
|
|
7242
|
+
const [highFrames, highCost] = anchors[i + 1];
|
|
7243
|
+
if (frames >= lowFrames && frames <= highFrames) {
|
|
7244
|
+
const t = (frames - lowFrames) / (highFrames - lowFrames);
|
|
7245
|
+
return lowCost + t * (highCost - lowCost);
|
|
7246
|
+
}
|
|
7247
|
+
}
|
|
7248
|
+
return frames <= anchors[0][0] ? anchors[0][1] : anchors[anchors.length - 1][1];
|
|
7249
|
+
}
|
|
6993
7250
|
var CHARACTER_TEMPLATES = ["mannequin", "bear", "cat", "dog", "horse", "lion"];
|
|
6994
7251
|
var PRO_FLASH_TEMPLATES = [...CHARACTER_TEMPLATES, "custom"];
|
|
6995
7252
|
function encodeAnimationJob(job) {
|
|
@@ -7038,7 +7295,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7038
7295
|
return new _PixelLabProvider(new PixelLabClient("download-only"));
|
|
7039
7296
|
}
|
|
7040
7297
|
supports(generator) {
|
|
7041
|
-
return generator === "1dir" || generator === "map" || generator === "pixflux" || generator === "tiles" || generator === "terrain" || generator === "imagePro" || generator === "character" || generator === "isometricTile" || generator === "objectPro" || generator === "uiAsset" || generator === "uiElement";
|
|
7298
|
+
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";
|
|
7042
7299
|
}
|
|
7043
7300
|
/**
|
|
7044
7301
|
* `inpaint` (`/inpaint-v3`, a mask) and `image-to-image` (`/edit-images-v2`,
|
|
@@ -7048,7 +7305,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7048
7305
|
* rather than a described edit — and `animate`/`animate-pixminimax`
|
|
7049
7306
|
* (`/animate-with-text-v3`, `/animate-pixminimax`), which animate any loose
|
|
7050
7307
|
* image from a text description with no character/object resource
|
|
7051
|
-
* required —
|
|
7308
|
+
* required — `animate-skeleton` (`/animate-with-skeleton-v3`, posing the
|
|
7309
|
+
* source from a supplied per-frame skeleton instead of a text description)
|
|
7310
|
+
* — and `interpolate` (`/interpolation-v2`, the in-betweens
|
|
7052
7311
|
* from one keyframe to another) and `edit-animation`
|
|
7053
7312
|
* (`/edit-animation-v2`, one text edit applied across a whole frame set).
|
|
7054
7313
|
* `outpaint` does not: there is no canvas-expansion endpoint in the API,
|
|
@@ -7056,7 +7315,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7056
7315
|
* outpaint path yet.
|
|
7057
7316
|
*/
|
|
7058
7317
|
supportsRevision(mode2) {
|
|
7059
|
-
return mode2 === "inpaint" || mode2 === "image-to-image" || mode2 === "reduce-colors" || mode2 === "correct-pixelart" || mode2 === "animate" || mode2 === "animate-pixminimax" || mode2 === "interpolate" || mode2 === "edit-animation";
|
|
7318
|
+
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";
|
|
7060
7319
|
}
|
|
7061
7320
|
/** PixelLab's own constraints: submissions must be >2s apart, and
|
|
7062
7321
|
* background jobs in flight are capped by subscription tier (Tier 1=8,
|
|
@@ -7087,6 +7346,10 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7087
7346
|
if (spec.revision?.mode === "reduce-colors" || spec.revision?.mode === "correct-pixelart") {
|
|
7088
7347
|
return { unit: "generations", amount: 0.1, candidates: 1 };
|
|
7089
7348
|
}
|
|
7349
|
+
if (spec.revision?.mode === "animate-skeleton") {
|
|
7350
|
+
const frames = spec.revision.frames ?? 8;
|
|
7351
|
+
return { unit: "generations", amount: Math.ceil(animateSkeletonCost(frames)), candidates: 1 };
|
|
7352
|
+
}
|
|
7090
7353
|
if (spec.revision?.mode === "interpolate" || spec.revision?.mode === "edit-animation") {
|
|
7091
7354
|
const width = spec.revision.sourceWidth ?? spec.width;
|
|
7092
7355
|
const height = spec.revision.sourceHeight ?? spec.height;
|
|
@@ -7100,6 +7363,13 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7100
7363
|
const base = Math.max(1, Math.ceil(width * height * frames / 65536));
|
|
7101
7364
|
return { unit: "generations", amount: spec.revision.enhancePrompt ? base + 0.05 : base, candidates: 1 };
|
|
7102
7365
|
}
|
|
7366
|
+
if (spec.revision?.engine === "pro-flash") {
|
|
7367
|
+
return {
|
|
7368
|
+
unit: "generations",
|
|
7369
|
+
amount: proFlashImageCost(spec.revision.sourceWidth ?? spec.width, spec.revision.sourceHeight ?? spec.height),
|
|
7370
|
+
candidates: 1
|
|
7371
|
+
};
|
|
7372
|
+
}
|
|
7103
7373
|
if (spec.revision) {
|
|
7104
7374
|
const width = spec.revision.sourceWidth ?? spec.width;
|
|
7105
7375
|
const height = spec.revision.sourceHeight ?? spec.height;
|
|
@@ -7114,6 +7384,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7114
7384
|
if (spec.generator === "objectPro") {
|
|
7115
7385
|
return { unit: "generations", amount: objectProCost(spec), candidates: 1 };
|
|
7116
7386
|
}
|
|
7387
|
+
if (spec.generator === "imageProFlash") {
|
|
7388
|
+
return { unit: "generations", amount: proFlashImageCost(spec.width, spec.height), candidates: 1 };
|
|
7389
|
+
}
|
|
7117
7390
|
return {
|
|
7118
7391
|
unit: "generations",
|
|
7119
7392
|
amount: generationCost(spec.width, spec.height, spec.generator),
|
|
@@ -7127,7 +7400,17 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7127
7400
|
`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`
|
|
7128
7401
|
);
|
|
7129
7402
|
}
|
|
7130
|
-
if (spec.revision?.
|
|
7403
|
+
if (spec.revision?.engine === "pro-flash") {
|
|
7404
|
+
const { sourceWidth: width, sourceHeight: height, mode: mode2 } = spec.revision;
|
|
7405
|
+
if (width != null && height != null && (width < 32 || height < 32 || width > 256 || height > 256 || width % 4 || height % 4)) {
|
|
7406
|
+
throw new Error(
|
|
7407
|
+
`PixelLab pro-flash ${mode2} source is ${width}x${height}; the API takes 32 to 256 pixels per side, in multiples of 4`
|
|
7408
|
+
);
|
|
7409
|
+
}
|
|
7410
|
+
if (spec.revision.strength != null) {
|
|
7411
|
+
throw new Error(`PixelLab pro-flash ${mode2} takes no strength; the edit applies in full`);
|
|
7412
|
+
}
|
|
7413
|
+
} else if (spec.revision?.mode === "inpaint") {
|
|
7131
7414
|
const { sourceWidth: width, sourceHeight: height } = spec.revision;
|
|
7132
7415
|
if (width != null && height != null && (width < 32 || height < 32 || width > 512 || height > 512)) {
|
|
7133
7416
|
throw new Error(`PixelLab inpaint source is ${width}x${height}; the API takes 32 to 512 pixels per side`);
|
|
@@ -7148,6 +7431,18 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7148
7431
|
throw new Error(`PixelLab correct-pixelart source is ${width}x${height}; the API takes at most 1024 pixels per side`);
|
|
7149
7432
|
}
|
|
7150
7433
|
}
|
|
7434
|
+
if (spec.revision?.mode === "animate-skeleton") {
|
|
7435
|
+
const { sourceWidth: width, sourceHeight: height, frames, skeletonTemplate } = spec.revision;
|
|
7436
|
+
if (width != null && height != null && (width > 256 || height > 256)) {
|
|
7437
|
+
throw new Error(`PixelLab animate-skeleton source is ${width}x${height}; the API takes at most 256 pixels per side`);
|
|
7438
|
+
}
|
|
7439
|
+
if (frames != null && (frames < 3 || frames > 15)) {
|
|
7440
|
+
throw new Error(`PixelLab animate-skeleton takes 3 to 15 frames; the keypoints file has ${frames}`);
|
|
7441
|
+
}
|
|
7442
|
+
if (skeletonTemplate && !CHARACTER_TEMPLATES.includes(skeletonTemplate)) {
|
|
7443
|
+
throw new Error(`PixelLab animate-skeleton template "${skeletonTemplate}" is not one of ${CHARACTER_TEMPLATES.join(", ")}`);
|
|
7444
|
+
}
|
|
7445
|
+
}
|
|
7151
7446
|
if (spec.revision?.mode === "animate" || spec.revision?.mode === "animate-pixminimax") {
|
|
7152
7447
|
const { sourceWidth: width, sourceHeight: height, mode: mode2, frames, lastFrameWidth, lastFrameHeight } = spec.revision;
|
|
7153
7448
|
if (width != null && height != null && (width > 256 || height > 256)) {
|
|
@@ -7208,6 +7503,19 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7208
7503
|
`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)`
|
|
7209
7504
|
);
|
|
7210
7505
|
}
|
|
7506
|
+
if (spec.generator === "imageProFlash") {
|
|
7507
|
+
if (spec.width < 16 || spec.height < 16 || spec.width > 256 || spec.height > 256 || spec.width % 4 || spec.height % 4) {
|
|
7508
|
+
throw new Error(
|
|
7509
|
+
`PixelLab imageProFlash is ${spec.width}x${spec.height}; the API takes 16 to 256 pixels per side, in multiples of 4`
|
|
7510
|
+
);
|
|
7511
|
+
}
|
|
7512
|
+
if (styleImages.length > 1) {
|
|
7513
|
+
throw new Error("PixelLab imageProFlash takes one style image; list at most one styleImages entry");
|
|
7514
|
+
}
|
|
7515
|
+
if (spec.styleTraits && !styleImages.length) {
|
|
7516
|
+
throw new Error("PixelLab imageProFlash: styleTraits choose what a style image lends; add a styleImages entry or drop them");
|
|
7517
|
+
}
|
|
7518
|
+
}
|
|
7211
7519
|
if (spec.generator === "uiElement" && (spec.width < 16 || spec.height < 16 || spec.width > 792 || spec.height > 688)) {
|
|
7212
7520
|
throw new Error(
|
|
7213
7521
|
`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)`
|
|
@@ -7561,7 +7869,8 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7561
7869
|
concept: character.concept ? readPose(spec, "concept image", character.concept) : void 0,
|
|
7562
7870
|
styleCharacterId: character.styleAnchor ? requireStyleObjectId(spec, context) : void 0,
|
|
7563
7871
|
styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
|
|
7564
|
-
styleTraits: character.styleTraits
|
|
7872
|
+
styleTraits: character.styleTraits,
|
|
7873
|
+
sourceImageId: character.mode === "pro-flash" ? context?.referenceSourceImageId : void 0
|
|
7565
7874
|
});
|
|
7566
7875
|
return { jobId: res2.character_id, metadata: { character: { kind: "base", characterId: res2.character_id, mode: character.mode, directions: character.directions, backgroundJobId: res2.background_job_id } } };
|
|
7567
7876
|
}
|
|
@@ -7696,7 +8005,8 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7696
8005
|
reference: object.reference ? readPose(spec, "reference sprite", object.reference) : void 0,
|
|
7697
8006
|
styleReference: styleImage ? { base64: styleImage.base64, format: styleImage.format } : void 0,
|
|
7698
8007
|
styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
|
|
7699
|
-
styleTraits: object.styleTraits
|
|
8008
|
+
styleTraits: object.styleTraits,
|
|
8009
|
+
sourceImageId: context?.referenceSourceImageId
|
|
7700
8010
|
});
|
|
7701
8011
|
return { jobId: res2.object_id, metadata: { objectPro: { kind: "base", objectId: res2.object_id, directions: object.directions, backgroundJobId: res2.background_job_id } } };
|
|
7702
8012
|
}
|
|
@@ -7995,6 +8305,19 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
7995
8305
|
});
|
|
7996
8306
|
return { jobId: res2.ui_asset_id, metadata: { backgroundJobId: res2.background_job_id } };
|
|
7997
8307
|
}
|
|
8308
|
+
if (spec.generator === "imageProFlash") {
|
|
8309
|
+
const style = styleImages[0];
|
|
8310
|
+
const res2 = await this.client.createImageProFlash({
|
|
8311
|
+
description: spec.prompt,
|
|
8312
|
+
width: spec.width,
|
|
8313
|
+
height: spec.height,
|
|
8314
|
+
noBackground: spec.noBackground,
|
|
8315
|
+
seed: spec.seed,
|
|
8316
|
+
styleImage: style ? { image: { base64: style.base64, format: style.format }, width: style.width, height: style.height } : void 0,
|
|
8317
|
+
styleTraits: spec.styleTraits
|
|
8318
|
+
});
|
|
8319
|
+
return { jobId: res2.background_job_id, metadata: { imageProFlash: proFlashRecord(res2) } };
|
|
8320
|
+
}
|
|
7998
8321
|
if (spec.generator === "uiElement") {
|
|
7999
8322
|
const concept = styleImages[0];
|
|
8000
8323
|
const res2 = await this.client.generateUiV2({
|
|
@@ -8148,6 +8471,32 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
8148
8471
|
const width = revision.sourceWidth;
|
|
8149
8472
|
const height = revision.sourceHeight;
|
|
8150
8473
|
const roles = revision.sourceMembers?.map((member) => member.role);
|
|
8474
|
+
if (revision.engine === "pro-flash") {
|
|
8475
|
+
if (revision.mode === "inpaint") {
|
|
8476
|
+
if (!revision.maskFile || !revision.maskSha256 || !revision.maskFormat) {
|
|
8477
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask is not ready`);
|
|
8478
|
+
}
|
|
8479
|
+
const maskBytes = readFileSync2(revision.maskFile);
|
|
8480
|
+
if (sha256(maskBytes) !== revision.maskSha256) {
|
|
8481
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask changed after the manifest was resolved`);
|
|
8482
|
+
}
|
|
8483
|
+
const res3 = await this.client.inpaintImageProFlash({
|
|
8484
|
+
image,
|
|
8485
|
+
maskImage: { base64: maskBytes.toString("base64"), format: revision.maskFormat },
|
|
8486
|
+
description: spec.prompt,
|
|
8487
|
+
noBackground: spec.noBackground,
|
|
8488
|
+
seed: spec.seed
|
|
8489
|
+
});
|
|
8490
|
+
return { jobId: res3.background_job_id, metadata: { imageProFlash: proFlashRecord(res3) } };
|
|
8491
|
+
}
|
|
8492
|
+
const res2 = await this.client.editImageProFlash({
|
|
8493
|
+
image,
|
|
8494
|
+
description: spec.prompt,
|
|
8495
|
+
noBackground: spec.noBackground,
|
|
8496
|
+
seed: spec.seed
|
|
8497
|
+
});
|
|
8498
|
+
return { jobId: res2.background_job_id, metadata: { imageProFlash: proFlashRecord(res2) } };
|
|
8499
|
+
}
|
|
8151
8500
|
if (revision.mode === "inpaint") {
|
|
8152
8501
|
if (!revision.maskFile || !revision.maskSha256 || !revision.maskFormat) {
|
|
8153
8502
|
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask is not ready`);
|
|
@@ -8243,6 +8592,27 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
8243
8592
|
});
|
|
8244
8593
|
return { jobId: res2.background_job_id };
|
|
8245
8594
|
}
|
|
8595
|
+
if (revision.mode === "animate-skeleton") {
|
|
8596
|
+
if (!revision.keypointsFile || !revision.keypointsSha256 || !revision.skeleton) {
|
|
8597
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision keypoints are not ready`);
|
|
8598
|
+
}
|
|
8599
|
+
const keypointsBytes = readFileSync2(revision.keypointsFile);
|
|
8600
|
+
if (sha256(keypointsBytes) !== revision.keypointsSha256) {
|
|
8601
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision keypoints changed after the manifest was resolved`);
|
|
8602
|
+
}
|
|
8603
|
+
const res2 = await this.client.animateWithSkeletonV3({
|
|
8604
|
+
firstFrame: image,
|
|
8605
|
+
firstFrameKeypoints: revision.skeleton.firstFrameKeypoints,
|
|
8606
|
+
keypoints: revision.skeleton.frames,
|
|
8607
|
+
direction: revision.direction,
|
|
8608
|
+
templateId: revision.skeletonTemplate,
|
|
8609
|
+
action: spec.prompt,
|
|
8610
|
+
description: revision.description,
|
|
8611
|
+
seed: spec.seed,
|
|
8612
|
+
noBackground: spec.noBackground
|
|
8613
|
+
});
|
|
8614
|
+
return { jobId: res2.background_job_id };
|
|
8615
|
+
}
|
|
8246
8616
|
if (revision.strength != null) {
|
|
8247
8617
|
throw new Error(
|
|
8248
8618
|
`${spec.styleId}/${spec.assetId}: PixelLab image-to-image revisions take no strength; edit-images-v2 always applies the full instruction`
|
|
@@ -8308,10 +8678,11 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
8308
8678
|
if (revisionMode === "reduce-colors" || revisionMode === "correct-pixelart") {
|
|
8309
8679
|
return this.pollCachedRevision(jobId, context);
|
|
8310
8680
|
}
|
|
8311
|
-
if (revisionMode === "animate" || revisionMode === "animate-pixminimax" || revisionMode === "interpolate" || revisionMode === "edit-animation") {
|
|
8681
|
+
if (revisionMode === "animate" || revisionMode === "animate-pixminimax" || revisionMode === "animate-skeleton" || revisionMode === "interpolate" || revisionMode === "edit-animation") {
|
|
8312
8682
|
return this.pollAnimateRevision(jobId, context);
|
|
8313
8683
|
}
|
|
8314
8684
|
if (context?.spec?.revision) return this.pollRevision(jobId);
|
|
8685
|
+
if (generator === "imageProFlash") return this.pollRevision(jobId);
|
|
8315
8686
|
if (generator === "pixflux") {
|
|
8316
8687
|
const file = path12.join(_PixelLabProvider.cacheDir(), `${jobId}.png`);
|
|
8317
8688
|
if (existsSync7(file)) {
|
|
@@ -8892,6 +9263,13 @@ function readPose(spec, what, image) {
|
|
|
8892
9263
|
}
|
|
8893
9264
|
return { base64: bytes.toString("base64"), format: image.format };
|
|
8894
9265
|
}
|
|
9266
|
+
function proFlashRecord(res) {
|
|
9267
|
+
return {
|
|
9268
|
+
imageId: res.image_id,
|
|
9269
|
+
sourceImageId: res.source_image_id,
|
|
9270
|
+
...res.estimated_generations != null ? { estimatedGenerations: res.estimated_generations } : {}
|
|
9271
|
+
};
|
|
9272
|
+
}
|
|
8895
9273
|
function editAnimationFrameCeiling(width, height) {
|
|
8896
9274
|
const side = Math.max(width, height);
|
|
8897
9275
|
if (side <= 64) return 16;
|
|
@@ -8990,9 +9368,9 @@ var RetroDiffusionClient = class {
|
|
|
8990
9368
|
if (!response.ok) throw new ProviderError("retrodiffusion", `Retro Diffusion download failed (${response.status})`, { status: response.status });
|
|
8991
9369
|
return Buffer.from(await response.arrayBuffer());
|
|
8992
9370
|
}
|
|
8993
|
-
async call(
|
|
9371
|
+
async call(path48, init = {}) {
|
|
8994
9372
|
if (!this.token) throw new Error("RD_API_KEY is not set");
|
|
8995
|
-
const response = await this.request(`${this.baseUrl}${
|
|
9373
|
+
const response = await this.request(`${this.baseUrl}${path48}`, {
|
|
8996
9374
|
...init,
|
|
8997
9375
|
headers: {
|
|
8998
9376
|
"Content-Type": "application/json",
|
|
@@ -10291,6 +10669,7 @@ async function resolveSpecs(loaded, filter) {
|
|
|
10291
10669
|
uiPieces: generator === "uiAsset" ? asset.pieces : void 0,
|
|
10292
10670
|
uiElements: generator === "uiAsset" ? asset.elements : void 0,
|
|
10293
10671
|
uiColorPalette: generator === "uiAsset" || generator === "uiElement" ? style.uiColorPalette : void 0,
|
|
10672
|
+
...generator === "imageProFlash" && style.styleTraits ? { styleTraits: style.styleTraits } : {},
|
|
10294
10673
|
palette: style.palette,
|
|
10295
10674
|
enforcePalette: style.enforcePalette,
|
|
10296
10675
|
noBackground: style.noBackground,
|
|
@@ -10535,6 +10914,8 @@ async function resolveSpecs(loaded, filter) {
|
|
|
10535
10914
|
const paletteImage = paletteImageFile ? await optionalRevisionImage(paletteImageFile, "revision palette image", "png") : null;
|
|
10536
10915
|
const lastFrameFile = asset.revision.lastFrame ? path13.resolve(root, asset.revision.lastFrame) : void 0;
|
|
10537
10916
|
const lastFrame = lastFrameFile ? await optionalRevisionImage(lastFrameFile, "revision last frame") : null;
|
|
10917
|
+
const keypointsFile = asset.revision.keypointsFile ? path13.resolve(root, asset.revision.keypointsFile) : void 0;
|
|
10918
|
+
const keypoints = keypointsFile ? await optionalSkeletonSet(keypointsFile) : null;
|
|
10538
10919
|
resolved.revision = {
|
|
10539
10920
|
mode: asset.revision.mode,
|
|
10540
10921
|
sourceAssetId: asset.revision.from,
|
|
@@ -10574,7 +10955,20 @@ async function resolveSpecs(loaded, filter) {
|
|
|
10574
10955
|
lastFrameFormat: lastFrame?.format ?? null
|
|
10575
10956
|
} : {},
|
|
10576
10957
|
...asset.revision.direction ? { direction: asset.revision.direction } : {},
|
|
10577
|
-
...asset.revision.enhancePrompt == null ? {} : { enhancePrompt: asset.revision.enhancePrompt }
|
|
10958
|
+
...asset.revision.enhancePrompt == null ? {} : { enhancePrompt: asset.revision.enhancePrompt },
|
|
10959
|
+
...keypointsFile ? {
|
|
10960
|
+
keypointsFile,
|
|
10961
|
+
keypointsSha256: keypoints?.hash ?? null,
|
|
10962
|
+
skeleton: keypoints?.skeleton ?? null,
|
|
10963
|
+
// The manifest's own `frames` field stays rejected for this
|
|
10964
|
+
// mode (superRefine, types.ts) — the real frame count comes
|
|
10965
|
+
// from the keypoints file once it exists, not a manifest
|
|
10966
|
+
// number, so plan can only know it once authored.
|
|
10967
|
+
...keypoints ? { frames: keypoints.skeleton.frames.length } : {}
|
|
10968
|
+
} : {},
|
|
10969
|
+
...asset.revision.skeletonTemplate ? { skeletonTemplate: asset.revision.skeletonTemplate } : {},
|
|
10970
|
+
...asset.revision.description ? { description: asset.revision.description } : {},
|
|
10971
|
+
...asset.revision.engine ? { engine: asset.revision.engine } : {}
|
|
10578
10972
|
};
|
|
10579
10973
|
}
|
|
10580
10974
|
if (asset.batch) {
|
|
@@ -10695,6 +11089,17 @@ async function optionalRevisionImage(file, label, requiredFormat) {
|
|
|
10695
11089
|
}
|
|
10696
11090
|
return { hash: sha256(bytes), ...metadata };
|
|
10697
11091
|
}
|
|
11092
|
+
async function optionalSkeletonSet(file) {
|
|
11093
|
+
if (!existsSync8(file)) return null;
|
|
11094
|
+
const bytes = await readFile6(file);
|
|
11095
|
+
let json;
|
|
11096
|
+
try {
|
|
11097
|
+
json = JSON.parse(bytes.toString("utf8"));
|
|
11098
|
+
} catch (error) {
|
|
11099
|
+
throw new Error(`revision keypoints file ${file} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
11100
|
+
}
|
|
11101
|
+
return { hash: sha256(bytes), skeleton: parseSkeletonSet(json, file) };
|
|
11102
|
+
}
|
|
10698
11103
|
async function revisionSourceMembers(stem, label) {
|
|
10699
11104
|
if (existsSync8(stem)) return null;
|
|
10700
11105
|
const at = (role) => memberPath(stem, role, 0, 2, MediaType.PNG);
|
|
@@ -11230,11 +11635,11 @@ import path15 from "path";
|
|
|
11230
11635
|
import { mkdir as mkdir5, readFile as readFile8, rename as rename5, rm as rm5, writeFile as writeFile5 } from "fs/promises";
|
|
11231
11636
|
import { existsSync as existsSync10 } from "fs";
|
|
11232
11637
|
import pathModule from "path";
|
|
11233
|
-
import { z as
|
|
11234
|
-
var HashCacheSchema =
|
|
11235
|
-
version:
|
|
11638
|
+
import { z as z4 } from "zod";
|
|
11639
|
+
var HashCacheSchema = z4.object({
|
|
11640
|
+
version: z4.literal(1),
|
|
11236
11641
|
/** objectId → sha256 of that object's image bytes. */
|
|
11237
|
-
hashes:
|
|
11642
|
+
hashes: z4.record(z4.string())
|
|
11238
11643
|
});
|
|
11239
11644
|
var SHA256_HEX = /^[a-f0-9]{64}$/;
|
|
11240
11645
|
function isSha256Hash(value) {
|
|
@@ -11243,10 +11648,10 @@ function isSha256Hash(value) {
|
|
|
11243
11648
|
function parseCache(value) {
|
|
11244
11649
|
return HashCacheSchema.parse(value);
|
|
11245
11650
|
}
|
|
11246
|
-
async function loadCache(
|
|
11247
|
-
if (!existsSync10(
|
|
11651
|
+
async function loadCache(path48) {
|
|
11652
|
+
if (!existsSync10(path48)) return { version: 1, hashes: {} };
|
|
11248
11653
|
try {
|
|
11249
|
-
const parsed = HashCacheSchema.safeParse(JSON.parse(await readFile8(
|
|
11654
|
+
const parsed = HashCacheSchema.safeParse(JSON.parse(await readFile8(path48, "utf8")));
|
|
11250
11655
|
if (!parsed.success) return { version: 1, hashes: {} };
|
|
11251
11656
|
return {
|
|
11252
11657
|
version: 1,
|
|
@@ -11258,18 +11663,18 @@ async function loadCache(path47) {
|
|
|
11258
11663
|
return { version: 1, hashes: {} };
|
|
11259
11664
|
}
|
|
11260
11665
|
}
|
|
11261
|
-
async function saveCache(
|
|
11666
|
+
async function saveCache(path48, cache) {
|
|
11262
11667
|
const sorted = {};
|
|
11263
11668
|
for (const key of Object.keys(cache.hashes).sort()) {
|
|
11264
11669
|
const hash = cache.hashes[key];
|
|
11265
11670
|
if (!isSha256Hash(hash)) throw new Error(`Refusing to cache invalid SHA-256 for ${key}`);
|
|
11266
11671
|
sorted[key] = hash;
|
|
11267
11672
|
}
|
|
11268
|
-
await mkdir5(pathModule.dirname(pathModule.resolve(
|
|
11269
|
-
const tmp = `${
|
|
11673
|
+
await mkdir5(pathModule.dirname(pathModule.resolve(path48)), { recursive: true });
|
|
11674
|
+
const tmp = `${path48}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
11270
11675
|
try {
|
|
11271
11676
|
await writeFile5(tmp, JSON.stringify({ version: 1, hashes: sorted }, null, 2) + "\n");
|
|
11272
|
-
await rename5(tmp,
|
|
11677
|
+
await rename5(tmp, path48);
|
|
11273
11678
|
} finally {
|
|
11274
11679
|
await rm5(tmp, { force: true });
|
|
11275
11680
|
}
|
|
@@ -12027,20 +12432,20 @@ async function applyTags(provider, decisions, existing, opts = {}) {
|
|
|
12027
12432
|
import { mkdir as mkdir7, readFile as readFile12, rename as rename6, rm as rm6, writeFile as writeFile8 } from "fs/promises";
|
|
12028
12433
|
import { existsSync as existsSync14 } from "fs";
|
|
12029
12434
|
import path18 from "path";
|
|
12030
|
-
import { z as
|
|
12031
|
-
var WorkspaceProjectSchema =
|
|
12032
|
-
id:
|
|
12435
|
+
import { z as z5 } from "zod";
|
|
12436
|
+
var WorkspaceProjectSchema = z5.object({
|
|
12437
|
+
id: z5.string().min(1),
|
|
12033
12438
|
/** Manifest path, relative to the catalog file's own directory. */
|
|
12034
|
-
manifest:
|
|
12439
|
+
manifest: z5.string().min(1),
|
|
12035
12440
|
/** Lockfile path, relative to the catalog file's own directory. */
|
|
12036
|
-
lock:
|
|
12037
|
-
provider:
|
|
12441
|
+
lock: z5.string().min(1),
|
|
12442
|
+
provider: z5.string().min(1).default("pixellab"),
|
|
12038
12443
|
/** Free-form label for a shared account, e.g. distinguishing sandboxes. */
|
|
12039
|
-
account:
|
|
12444
|
+
account: z5.string().optional()
|
|
12040
12445
|
}).strict();
|
|
12041
|
-
var WorkspaceSchema =
|
|
12042
|
-
version:
|
|
12043
|
-
projects:
|
|
12446
|
+
var WorkspaceSchema = z5.object({
|
|
12447
|
+
version: z5.literal(1),
|
|
12448
|
+
projects: z5.array(WorkspaceProjectSchema).default([])
|
|
12044
12449
|
}).strict();
|
|
12045
12450
|
function parseWorkspace(raw) {
|
|
12046
12451
|
const parsed = WorkspaceSchema.safeParse(raw);
|
|
@@ -13225,62 +13630,62 @@ import path25 from "path";
|
|
|
13225
13630
|
import { existsSync as existsSync17 } from "fs";
|
|
13226
13631
|
import { copyFile, mkdir as mkdir9, readFile as readFile16, rename as rename8, rm as rm8, writeFile as writeFile11 } from "fs/promises";
|
|
13227
13632
|
import path24 from "path";
|
|
13228
|
-
import { z as
|
|
13633
|
+
import { z as z7 } from "zod";
|
|
13229
13634
|
|
|
13230
13635
|
// src/manifest-edit.ts
|
|
13231
13636
|
import { readFile as readFile15, rename as rename7, rm as rm7, writeFile as writeFile10 } from "fs/promises";
|
|
13232
13637
|
import path23 from "path";
|
|
13233
|
-
import { z as
|
|
13234
|
-
var HexSha =
|
|
13235
|
-
var AssetPatchSchema =
|
|
13236
|
-
prompt:
|
|
13638
|
+
import { z as z6 } from "zod";
|
|
13639
|
+
var HexSha = z6.string().regex(/^[0-9a-f]{64}$/);
|
|
13640
|
+
var AssetPatchSchema = z6.object({
|
|
13641
|
+
prompt: z6.string().optional(),
|
|
13237
13642
|
/** Per-style override for the style being viewed; null removes it. */
|
|
13238
|
-
promptForStyle:
|
|
13239
|
-
category:
|
|
13240
|
-
width:
|
|
13241
|
-
height:
|
|
13242
|
-
size:
|
|
13243
|
-
tags:
|
|
13643
|
+
promptForStyle: z6.object({ styleId: z6.string().min(1), prompt: z6.string().nullable() }).optional(),
|
|
13644
|
+
category: z6.string().nullable().optional(),
|
|
13645
|
+
width: z6.number().int().nullable().optional(),
|
|
13646
|
+
height: z6.number().int().nullable().optional(),
|
|
13647
|
+
size: z6.number().int().nullable().optional(),
|
|
13648
|
+
tags: z6.array(z6.string()).optional()
|
|
13244
13649
|
}).strict();
|
|
13245
|
-
var NewStateSchema =
|
|
13650
|
+
var NewStateSchema = z6.object({
|
|
13246
13651
|
/** Asset id of the parent this states; must already exist. */
|
|
13247
|
-
of:
|
|
13248
|
-
paletteFromReference:
|
|
13249
|
-
canvas:
|
|
13652
|
+
of: z6.string().min(1),
|
|
13653
|
+
paletteFromReference: z6.boolean().optional(),
|
|
13654
|
+
canvas: z6.object({ width: z6.number().int().min(16).max(256), height: z6.number().int().min(16).max(256) }).strict().optional()
|
|
13250
13655
|
}).strict();
|
|
13251
|
-
var NewAnimationSchema =
|
|
13656
|
+
var NewAnimationSchema = z6.object({
|
|
13252
13657
|
/** Asset id of the parent this animates; must already exist. */
|
|
13253
|
-
of:
|
|
13658
|
+
of: z6.string().min(1),
|
|
13254
13659
|
/** A PixelLab template id (`character` only; `objectPro` has no template concept). */
|
|
13255
|
-
template:
|
|
13660
|
+
template: z6.string().min(1).optional(),
|
|
13256
13661
|
direction: CharacterDirectionSchema.optional(),
|
|
13257
|
-
frames:
|
|
13258
|
-
fps:
|
|
13662
|
+
frames: z6.number().int().min(4).max(16).optional(),
|
|
13663
|
+
fps: z6.number().int().min(1).max(60).optional(),
|
|
13259
13664
|
mode: CharacterAnimationModeSchema.optional(),
|
|
13260
13665
|
/** What is being animated, when the parent's own description would mislead the model (`character` only). */
|
|
13261
|
-
subject:
|
|
13262
|
-
enhancePrompt:
|
|
13666
|
+
subject: z6.string().min(1).optional(),
|
|
13667
|
+
enhancePrompt: z6.boolean().optional()
|
|
13263
13668
|
}).strict();
|
|
13264
|
-
var NewAssetSchema =
|
|
13265
|
-
prompt:
|
|
13266
|
-
category:
|
|
13267
|
-
width:
|
|
13268
|
-
height:
|
|
13269
|
-
size:
|
|
13270
|
-
tags:
|
|
13669
|
+
var NewAssetSchema = z6.object({
|
|
13670
|
+
prompt: z6.string(),
|
|
13671
|
+
category: z6.string().optional(),
|
|
13672
|
+
width: z6.number().int().optional(),
|
|
13673
|
+
height: z6.number().int().optional(),
|
|
13674
|
+
size: z6.number().int().optional(),
|
|
13675
|
+
tags: z6.array(z6.string()).optional(),
|
|
13271
13676
|
/** Restrict to these styles; empty or omitted means every style. */
|
|
13272
|
-
styles:
|
|
13677
|
+
styles: z6.array(z6.string().min(1)).optional(),
|
|
13273
13678
|
/**
|
|
13274
13679
|
* A controlled regeneration of another asset in the same manifest,
|
|
13275
13680
|
* instead of a fresh generation. `inpaint` needs a mask upload the
|
|
13276
13681
|
* gallery does not offer yet, so only `image-to-image` can be created
|
|
13277
13682
|
* here; hand-edit the manifest for the other modes.
|
|
13278
13683
|
*/
|
|
13279
|
-
revision:
|
|
13280
|
-
mode:
|
|
13684
|
+
revision: z6.object({
|
|
13685
|
+
mode: z6.literal("image-to-image"),
|
|
13281
13686
|
/** Asset id of the parent this revises; must already exist. */
|
|
13282
|
-
from:
|
|
13283
|
-
strength:
|
|
13687
|
+
from: z6.string().min(1),
|
|
13688
|
+
strength: z6.number().min(0).max(1).optional()
|
|
13284
13689
|
}).strict().optional(),
|
|
13285
13690
|
/** A pose or outfit of an existing `character`/`objectPro` base or state. */
|
|
13286
13691
|
state: NewStateSchema.optional(),
|
|
@@ -13296,58 +13701,58 @@ var CANDIDATE_OPTION = {
|
|
|
13296
13701
|
comfyui: "numImages",
|
|
13297
13702
|
scenario: "numOutputs"
|
|
13298
13703
|
};
|
|
13299
|
-
var ManifestEditSchema =
|
|
13300
|
-
|
|
13301
|
-
action:
|
|
13704
|
+
var ManifestEditSchema = z6.discriminatedUnion("action", [
|
|
13705
|
+
z6.object({
|
|
13706
|
+
action: z6.literal("patch-asset"),
|
|
13302
13707
|
/** Workspace project id; omitted for a single-project gallery. */
|
|
13303
|
-
project:
|
|
13304
|
-
assetId:
|
|
13708
|
+
project: z6.string().min(1).optional(),
|
|
13709
|
+
assetId: z6.string().min(1),
|
|
13305
13710
|
/** Manifest bytes the page last saw; a mismatch refuses the write. */
|
|
13306
13711
|
expectedSha256: HexSha,
|
|
13307
13712
|
patch: AssetPatchSchema
|
|
13308
13713
|
}).strict(),
|
|
13309
|
-
|
|
13310
|
-
action:
|
|
13311
|
-
project:
|
|
13312
|
-
assetId:
|
|
13714
|
+
z6.object({
|
|
13715
|
+
action: z6.literal("add-asset"),
|
|
13716
|
+
project: z6.string().min(1).optional(),
|
|
13717
|
+
assetId: z6.string().min(1).regex(/^[^/\\]+$/, "asset ids cannot contain slashes"),
|
|
13313
13718
|
expectedSha256: HexSha,
|
|
13314
13719
|
asset: NewAssetSchema
|
|
13315
13720
|
}).strict(),
|
|
13316
|
-
|
|
13317
|
-
action:
|
|
13318
|
-
project:
|
|
13319
|
-
assetId:
|
|
13320
|
-
styleId:
|
|
13721
|
+
z6.object({
|
|
13722
|
+
action: z6.literal("set-source"),
|
|
13723
|
+
project: z6.string().min(1).optional(),
|
|
13724
|
+
assetId: z6.string().min(1),
|
|
13725
|
+
styleId: z6.string().min(1),
|
|
13321
13726
|
/** Manifest-relative path of the art that stands in for this asset in this style. */
|
|
13322
|
-
source:
|
|
13727
|
+
source: z6.string().min(1),
|
|
13323
13728
|
expectedSha256: HexSha
|
|
13324
13729
|
}).strict(),
|
|
13325
|
-
|
|
13326
|
-
action:
|
|
13327
|
-
project:
|
|
13328
|
-
assetId:
|
|
13329
|
-
styleId:
|
|
13730
|
+
z6.object({
|
|
13731
|
+
action: z6.literal("clear-source"),
|
|
13732
|
+
project: z6.string().min(1).optional(),
|
|
13733
|
+
assetId: z6.string().min(1),
|
|
13734
|
+
styleId: z6.string().min(1),
|
|
13330
13735
|
expectedSha256: HexSha
|
|
13331
13736
|
}).strict(),
|
|
13332
|
-
|
|
13333
|
-
action:
|
|
13334
|
-
project:
|
|
13335
|
-
styleId:
|
|
13737
|
+
z6.object({
|
|
13738
|
+
action: z6.literal("patch-style"),
|
|
13739
|
+
project: z6.string().min(1).optional(),
|
|
13740
|
+
styleId: z6.string().min(1),
|
|
13336
13741
|
expectedSha256: HexSha,
|
|
13337
|
-
patch:
|
|
13742
|
+
patch: z6.object({
|
|
13338
13743
|
/** Candidates per generation, written to the provider's own option. */
|
|
13339
|
-
candidates:
|
|
13744
|
+
candidates: z6.number().int().min(1).max(64).optional(),
|
|
13340
13745
|
/** Empty clears the style's own value (inherit, or the default). */
|
|
13341
|
-
promptPrefix:
|
|
13342
|
-
promptSuffix:
|
|
13746
|
+
promptPrefix: z6.string().optional(),
|
|
13747
|
+
promptSuffix: z6.string().optional(),
|
|
13343
13748
|
/** `#rrggbb` values; null or empty clears the style's own palette. */
|
|
13344
|
-
palette:
|
|
13749
|
+
palette: z6.array(z6.string().regex(/^#?[0-9a-f]{6}$/i, "expected a six-digit hex colour")).max(256).nullable().optional(),
|
|
13345
13750
|
/** Snap downloaded art to the palette; false clears the style's own value. */
|
|
13346
|
-
enforcePalette:
|
|
13751
|
+
enforcePalette: z6.boolean().optional(),
|
|
13347
13752
|
/** Provider view name (PixelLab: low top-down, high top-down, side); empty clears. */
|
|
13348
|
-
view:
|
|
13753
|
+
view: z6.string().max(64).nullable().optional(),
|
|
13349
13754
|
/** pixflux only; null clears the style's own value. */
|
|
13350
|
-
noBackground:
|
|
13755
|
+
noBackground: z6.boolean().nullable().optional()
|
|
13351
13756
|
}).strict().refine((patch) => Object.keys(patch).length > 0, { message: "nothing to change" })
|
|
13352
13757
|
}).strict()
|
|
13353
13758
|
]);
|
|
@@ -13630,35 +14035,35 @@ async function detachHandEdit(loaded, spec, opts = {}) {
|
|
|
13630
14035
|
});
|
|
13631
14036
|
return { manifestSha256: result.sha256, changed: result.changed };
|
|
13632
14037
|
}
|
|
13633
|
-
var CompanionOutputSchema =
|
|
14038
|
+
var CompanionOutputSchema = z7.object({
|
|
13634
14039
|
/** Output role for a set member; null for a single image. */
|
|
13635
|
-
role:
|
|
14040
|
+
role: z7.string().nullable(),
|
|
13636
14041
|
/** sha256 of the generated file this member started from; null when it started from untracked art. */
|
|
13637
|
-
basedOn:
|
|
14042
|
+
basedOn: z7.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
13638
14043
|
/** sha256 of the member as saved, so a later change by another tool is visible. */
|
|
13639
|
-
sha256:
|
|
14044
|
+
sha256: z7.string().regex(/^[0-9a-f]{64}$/)
|
|
13640
14045
|
}).strict();
|
|
13641
|
-
var CompanionV2Schema =
|
|
13642
|
-
version:
|
|
14046
|
+
var CompanionV2Schema = z7.object({
|
|
14047
|
+
version: z7.literal(2),
|
|
13643
14048
|
/** Editor identity the bridge reported, e.g. `pixelorama@v1.2.2-stable`. */
|
|
13644
|
-
editor:
|
|
13645
|
-
protocol:
|
|
13646
|
-
savedAt:
|
|
14049
|
+
editor: z7.string().min(1),
|
|
14050
|
+
protocol: z7.number().int().positive(),
|
|
14051
|
+
savedAt: z7.string().datetime(),
|
|
13647
14052
|
/** Basename of the layered project file beside the edit, when one was kept. */
|
|
13648
|
-
project:
|
|
14053
|
+
project: z7.string().min(1).nullable(),
|
|
13649
14054
|
/** One entry per file, in output order. */
|
|
13650
|
-
outputs:
|
|
14055
|
+
outputs: z7.array(CompanionOutputSchema).min(1)
|
|
13651
14056
|
}).strict();
|
|
13652
|
-
var CompanionV1Schema =
|
|
13653
|
-
version:
|
|
13654
|
-
basedOn:
|
|
13655
|
-
sha256:
|
|
13656
|
-
editor:
|
|
13657
|
-
protocol:
|
|
13658
|
-
savedAt:
|
|
13659
|
-
project:
|
|
14057
|
+
var CompanionV1Schema = z7.object({
|
|
14058
|
+
version: z7.literal(1),
|
|
14059
|
+
basedOn: z7.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
14060
|
+
sha256: z7.string().regex(/^[0-9a-f]{64}$/),
|
|
14061
|
+
editor: z7.string().min(1),
|
|
14062
|
+
protocol: z7.number().int().positive(),
|
|
14063
|
+
savedAt: z7.string().datetime(),
|
|
14064
|
+
project: z7.string().min(1).nullable()
|
|
13660
14065
|
}).strict();
|
|
13661
|
-
var HandEditCompanionSchema =
|
|
14066
|
+
var HandEditCompanionSchema = z7.union([CompanionV2Schema, CompanionV1Schema]).transform(
|
|
13662
14067
|
(value) => value.version === 2 ? value : {
|
|
13663
14068
|
version: 2,
|
|
13664
14069
|
editor: value.editor,
|
|
@@ -13817,41 +14222,41 @@ import path28 from "path";
|
|
|
13817
14222
|
|
|
13818
14223
|
// src/gallery/edit.ts
|
|
13819
14224
|
import path26 from "path";
|
|
13820
|
-
import { z as
|
|
13821
|
-
var Base64 =
|
|
13822
|
-
var HandEditRequestSchema =
|
|
13823
|
-
|
|
13824
|
-
action:
|
|
13825
|
-
project:
|
|
13826
|
-
assetId:
|
|
13827
|
-
styleId:
|
|
13828
|
-
expectedSha256:
|
|
14225
|
+
import { z as z8 } from "zod";
|
|
14226
|
+
var Base64 = z8.string().regex(/^[A-Za-z0-9+/]*={0,2}$/).max(Math.ceil(MAX_HAND_EDIT_BYTES / 3) * 4);
|
|
14227
|
+
var HandEditRequestSchema = z8.discriminatedUnion("action", [
|
|
14228
|
+
z8.object({
|
|
14229
|
+
action: z8.literal("start-edit"),
|
|
14230
|
+
project: z8.string().min(1).optional(),
|
|
14231
|
+
assetId: z8.string().min(1),
|
|
14232
|
+
styleId: z8.string().min(1),
|
|
14233
|
+
expectedSha256: z8.string().regex(/^[0-9a-f]{64}$/),
|
|
13829
14234
|
/** Also launch the author's editor on the file. */
|
|
13830
|
-
open:
|
|
14235
|
+
open: z8.boolean().optional()
|
|
13831
14236
|
}).strict(),
|
|
13832
|
-
|
|
13833
|
-
action:
|
|
13834
|
-
project:
|
|
13835
|
-
assetId:
|
|
13836
|
-
styleId:
|
|
13837
|
-
expectedSha256:
|
|
14237
|
+
z8.object({
|
|
14238
|
+
action: z8.literal("detach-edit"),
|
|
14239
|
+
project: z8.string().min(1).optional(),
|
|
14240
|
+
assetId: z8.string().min(1),
|
|
14241
|
+
styleId: z8.string().min(1),
|
|
14242
|
+
expectedSha256: z8.string().regex(/^[0-9a-f]{64}$/)
|
|
13838
14243
|
}).strict(),
|
|
13839
14244
|
/** From the in-browser editor: the page holds the bytes, the server validates and writes. */
|
|
13840
|
-
|
|
13841
|
-
action:
|
|
13842
|
-
project:
|
|
13843
|
-
assetId:
|
|
13844
|
-
styleId:
|
|
13845
|
-
expectedSha256:
|
|
14245
|
+
z8.object({
|
|
14246
|
+
action: z8.literal("save-edit"),
|
|
14247
|
+
project: z8.string().min(1).optional(),
|
|
14248
|
+
assetId: z8.string().min(1),
|
|
14249
|
+
styleId: z8.string().min(1),
|
|
14250
|
+
expectedSha256: z8.string().regex(/^[0-9a-f]{64}$/),
|
|
13846
14251
|
/** The flattened image; for a frame set, `frames` instead. */
|
|
13847
14252
|
png: Base64.min(1).optional(),
|
|
13848
14253
|
/** Every frame of a set, tagged with the role it was opened under (null for one added in the editor). */
|
|
13849
|
-
frames:
|
|
14254
|
+
frames: z8.array(z8.object({ role: z8.string().min(1).nullable(), png: Base64.min(1) }).strict()).min(1).max(256).optional(),
|
|
13850
14255
|
/** The editor's layered project file, kept beside the edit. */
|
|
13851
14256
|
pxo: Base64.optional(),
|
|
13852
14257
|
/** Editor identity from the bridge's ready message. */
|
|
13853
|
-
editor:
|
|
13854
|
-
protocol:
|
|
14258
|
+
editor: z8.string().min(1).max(200),
|
|
14259
|
+
protocol: z8.number().int().positive()
|
|
13855
14260
|
}).strict()
|
|
13856
14261
|
]);
|
|
13857
14262
|
function createGalleryEditHandler(opts) {
|
|
@@ -15035,7 +15440,7 @@ async function serveGallery(opts) {
|
|
|
15035
15440
|
|
|
15036
15441
|
// src/gallery/generate.ts
|
|
15037
15442
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
15038
|
-
import { z as
|
|
15443
|
+
import { z as z9 } from "zod";
|
|
15039
15444
|
|
|
15040
15445
|
// src/pipeline/poll.ts
|
|
15041
15446
|
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -15315,7 +15720,11 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
15315
15720
|
...spec.revision.fps == null ? {} : { fps: spec.revision.fps },
|
|
15316
15721
|
...spec.revision.lastFrameSha256 ? { lastFrameSha256: spec.revision.lastFrameSha256 } : {},
|
|
15317
15722
|
...spec.revision.direction ? { direction: spec.revision.direction } : {},
|
|
15318
|
-
...spec.revision.enhancePrompt == null ? {} : { enhancePrompt: spec.revision.enhancePrompt }
|
|
15723
|
+
...spec.revision.enhancePrompt == null ? {} : { enhancePrompt: spec.revision.enhancePrompt },
|
|
15724
|
+
...spec.revision.keypointsSha256 ? { keypointsSha256: spec.revision.keypointsSha256 } : {},
|
|
15725
|
+
...spec.revision.skeletonTemplate ? { skeletonTemplate: spec.revision.skeletonTemplate } : {},
|
|
15726
|
+
...spec.revision.description ? { description: spec.revision.description } : {},
|
|
15727
|
+
...spec.revision.engine ? { engine: spec.revision.engine } : {}
|
|
15319
15728
|
} : null,
|
|
15320
15729
|
outfit: spec.character?.kind === "outfit" && outfitParentEntry ? {
|
|
15321
15730
|
sourceAssetId: spec.character.parentAssetId,
|
|
@@ -15359,8 +15768,10 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
15359
15768
|
path: currentEntryOutputPath(parentEntry, spec.character.parentSpec, index),
|
|
15360
15769
|
role: output.role
|
|
15361
15770
|
})) : void 0;
|
|
15771
|
+
const referenceSourceImageId = ownedReferenceImageId(spec, lock, provider.id);
|
|
15362
15772
|
const { jobId, metadata } = await provider.submit(spec, refs, {
|
|
15363
15773
|
...previousJobId ? { previousJobId } : {},
|
|
15774
|
+
...referenceSourceImageId ? { referenceSourceImageId } : {},
|
|
15364
15775
|
...parentEntry?.objectId ? { parentObjectId: parentEntry.objectId } : {},
|
|
15365
15776
|
...anchorEntry?.objectId ? { styleObjectId: anchorEntry.objectId } : {},
|
|
15366
15777
|
...parentOutputs ? { parentOutputs } : {},
|
|
@@ -15427,6 +15838,17 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
15427
15838
|
}
|
|
15428
15839
|
return { submitted, failed, spent, unit };
|
|
15429
15840
|
}
|
|
15841
|
+
function ownedReferenceImageId(spec, lock, providerId) {
|
|
15842
|
+
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;
|
|
15843
|
+
if (!sha2562) return void 0;
|
|
15844
|
+
for (const entry of Object.values(lock.entries)) {
|
|
15845
|
+
if (entry.provider !== providerId || entry.generator !== "imageProFlash" || entry.status !== "downloaded") continue;
|
|
15846
|
+
if (entry.outputs.length !== 1 || entry.outputs[0].sha256 !== sha2562) continue;
|
|
15847
|
+
const recorded = entry.providerMetadata?.[providerId]?.imageProFlash;
|
|
15848
|
+
if (typeof recorded?.sourceImageId === "string" && recorded.sourceImageId) return recorded.sourceImageId;
|
|
15849
|
+
}
|
|
15850
|
+
return void 0;
|
|
15851
|
+
}
|
|
15430
15852
|
|
|
15431
15853
|
// src/pick/server.ts
|
|
15432
15854
|
import { existsSync as existsSync21 } from "fs";
|
|
@@ -16118,26 +16540,26 @@ async function runPicker(provider, lock, lockPath, opts = {}) {
|
|
|
16118
16540
|
}
|
|
16119
16541
|
|
|
16120
16542
|
// src/gallery/generate.ts
|
|
16121
|
-
var GenerateRequestSchema =
|
|
16122
|
-
project:
|
|
16123
|
-
keys:
|
|
16543
|
+
var GenerateRequestSchema = z9.object({
|
|
16544
|
+
project: z9.string().min(1).optional(),
|
|
16545
|
+
keys: z9.array(z9.string().min(1)).min(1).max(500),
|
|
16124
16546
|
/**
|
|
16125
16547
|
* Regenerate work that is up to date, as `gen --force` does, and let the
|
|
16126
16548
|
* fetch replace a locally modified or untracked file. With `restore`, put
|
|
16127
16549
|
* the recorded bytes back over a modified file.
|
|
16128
16550
|
*/
|
|
16129
|
-
force:
|
|
16551
|
+
force: z9.boolean().optional(),
|
|
16130
16552
|
/** Advance in-flight, review, or selected work without submitting anything. */
|
|
16131
|
-
resume:
|
|
16553
|
+
resume: z9.boolean().optional(),
|
|
16132
16554
|
/** Re-download downloaded outputs and replace files whose object changed upstream. */
|
|
16133
|
-
refresh:
|
|
16555
|
+
refresh: z9.boolean().optional(),
|
|
16134
16556
|
/** Put recorded outputs back on disk from the cache or the provider, without generating. */
|
|
16135
|
-
restore:
|
|
16557
|
+
restore: z9.boolean().optional(),
|
|
16136
16558
|
/**
|
|
16137
16559
|
* Bring a replaced generation back: 1-based position in the record's
|
|
16138
16560
|
* history (newest first) or an output hash prefix. One key at a time.
|
|
16139
16561
|
*/
|
|
16140
|
-
revert:
|
|
16562
|
+
revert: z9.string().min(1).max(64).optional()
|
|
16141
16563
|
}).strict().refine((request) => [request.resume, request.refresh, request.restore, request.revert !== void 0].filter(Boolean).length <= 1, {
|
|
16142
16564
|
message: "resume, refresh, restore, and revert are exclusive"
|
|
16143
16565
|
}).refine((request) => request.revert === void 0 || request.keys.length === 1, { message: "revert takes one key" });
|
|
@@ -19023,11 +19445,11 @@ import { readFile as readFile28 } from "fs/promises";
|
|
|
19023
19445
|
import path41 from "path";
|
|
19024
19446
|
import { existsSync as existsSync30 } from "fs";
|
|
19025
19447
|
import { readFile as readFile27 } from "fs/promises";
|
|
19026
|
-
import { z as
|
|
19448
|
+
import { z as z10 } from "zod";
|
|
19027
19449
|
var SHA256_RE = /^[0-9a-f]{64}$/;
|
|
19028
19450
|
var HEX_RE = /^#[0-9a-f]{6}$/;
|
|
19029
19451
|
var MAX_REDMEAN_DISTANCE = 765;
|
|
19030
|
-
var QualityPathSchema =
|
|
19452
|
+
var QualityPathSchema = z10.string().min(1).refine(
|
|
19031
19453
|
(value) => !path41.posix.isAbsolute(value) && !value.includes("\\"),
|
|
19032
19454
|
"expected a portable relative path"
|
|
19033
19455
|
);
|
|
@@ -19041,53 +19463,53 @@ var DEFAULT_QUALITY_TOLERANCES = {
|
|
|
19041
19463
|
maxEdgeContrastDrop: 0.03,
|
|
19042
19464
|
maxIsolatedPixelIncrease: 5e-3
|
|
19043
19465
|
};
|
|
19044
|
-
var QualityToleranceSchema =
|
|
19045
|
-
requireExactHash:
|
|
19046
|
-
maxColorCountIncrease:
|
|
19047
|
-
maxNewColors:
|
|
19048
|
-
maxTransparencyDelta:
|
|
19049
|
-
maxPartialAlphaIncrease:
|
|
19050
|
-
maxEdgeDensityDelta:
|
|
19051
|
-
maxEdgeContrastDrop:
|
|
19052
|
-
maxIsolatedPixelIncrease:
|
|
19466
|
+
var QualityToleranceSchema = z10.object({
|
|
19467
|
+
requireExactHash: z10.boolean(),
|
|
19468
|
+
maxColorCountIncrease: z10.number().int().min(0),
|
|
19469
|
+
maxNewColors: z10.number().int().min(0),
|
|
19470
|
+
maxTransparencyDelta: z10.number().min(0).max(1),
|
|
19471
|
+
maxPartialAlphaIncrease: z10.number().min(0).max(1),
|
|
19472
|
+
maxEdgeDensityDelta: z10.number().min(0).max(1),
|
|
19473
|
+
maxEdgeContrastDrop: z10.number().min(0).max(1),
|
|
19474
|
+
maxIsolatedPixelIncrease: z10.number().min(0).max(1)
|
|
19053
19475
|
}).strict();
|
|
19054
|
-
var ImageQualityMetricsSchema =
|
|
19055
|
-
sha256:
|
|
19056
|
-
width:
|
|
19057
|
-
height:
|
|
19058
|
-
colorCount:
|
|
19059
|
-
colors:
|
|
19060
|
-
transparency:
|
|
19061
|
-
partialAlpha:
|
|
19062
|
-
edgeDensity:
|
|
19063
|
-
meanEdgeContrast:
|
|
19064
|
-
isolatedPixelRatio:
|
|
19476
|
+
var ImageQualityMetricsSchema = z10.object({
|
|
19477
|
+
sha256: z10.string().regex(SHA256_RE),
|
|
19478
|
+
width: z10.number().int().min(1),
|
|
19479
|
+
height: z10.number().int().min(1),
|
|
19480
|
+
colorCount: z10.number().int().min(0),
|
|
19481
|
+
colors: z10.array(z10.string().regex(HEX_RE)),
|
|
19482
|
+
transparency: z10.number().min(0).max(1),
|
|
19483
|
+
partialAlpha: z10.number().min(0).max(1),
|
|
19484
|
+
edgeDensity: z10.number().min(0).max(1),
|
|
19485
|
+
meanEdgeContrast: z10.number().min(0).max(1),
|
|
19486
|
+
isolatedPixelRatio: z10.number().min(0).max(1)
|
|
19065
19487
|
}).strict();
|
|
19066
|
-
var QualityBaselineCaseSchema =
|
|
19067
|
-
id:
|
|
19488
|
+
var QualityBaselineCaseSchema = z10.object({
|
|
19489
|
+
id: z10.string().regex(/^[a-z0-9][a-z0-9/_-]*$/),
|
|
19068
19490
|
file: QualityPathSchema,
|
|
19069
|
-
record:
|
|
19491
|
+
record: z10.object({
|
|
19070
19492
|
path: QualityPathSchema,
|
|
19071
|
-
sha256:
|
|
19493
|
+
sha256: z10.string().regex(SHA256_RE)
|
|
19072
19494
|
}).strict().optional(),
|
|
19073
19495
|
expected: ImageQualityMetricsSchema,
|
|
19074
19496
|
tolerances: QualityToleranceSchema
|
|
19075
19497
|
}).strict();
|
|
19076
|
-
var QualityBaselineSchema =
|
|
19077
|
-
$schema:
|
|
19078
|
-
format:
|
|
19079
|
-
schemaVersion:
|
|
19080
|
-
cases:
|
|
19498
|
+
var QualityBaselineSchema = z10.object({
|
|
19499
|
+
$schema: z10.string().url().optional(),
|
|
19500
|
+
format: z10.literal("pixelkiln-quality-baseline"),
|
|
19501
|
+
schemaVersion: z10.literal(1),
|
|
19502
|
+
cases: z10.array(QualityBaselineCaseSchema).min(1)
|
|
19081
19503
|
}).strict().superRefine((baseline, context) => {
|
|
19082
19504
|
const ids = baseline.cases.map((entry) => entry.id);
|
|
19083
19505
|
if (new Set(ids).size !== ids.length) {
|
|
19084
|
-
context.addIssue({ code:
|
|
19506
|
+
context.addIssue({ code: z10.ZodIssueCode.custom, path: ["cases"], message: "duplicate case id" });
|
|
19085
19507
|
}
|
|
19086
19508
|
});
|
|
19087
|
-
var QualityInputSchema =
|
|
19088
|
-
id:
|
|
19089
|
-
path:
|
|
19090
|
-
record:
|
|
19509
|
+
var QualityInputSchema = z10.object({
|
|
19510
|
+
id: z10.string().regex(/^[a-z0-9][a-z0-9/_-]*$/),
|
|
19511
|
+
path: z10.string().min(1),
|
|
19512
|
+
record: z10.string().min(1).optional(),
|
|
19091
19513
|
tolerances: QualityToleranceSchema.partial().optional()
|
|
19092
19514
|
}).strict();
|
|
19093
19515
|
function message4(error) {
|
|
@@ -19189,7 +19611,7 @@ async function measureImageQuality(file) {
|
|
|
19189
19611
|
}
|
|
19190
19612
|
}
|
|
19191
19613
|
function resolveQualityInputs(raw, inputsFilePath) {
|
|
19192
|
-
const parsed =
|
|
19614
|
+
const parsed = z10.array(QualityInputSchema).min(1).safeParse(raw);
|
|
19193
19615
|
if (!parsed.success) {
|
|
19194
19616
|
throw new Error(
|
|
19195
19617
|
"--inputs must be a non-empty JSON array of quality cases:\n" + parsed.error.issues.map((issue) => ` ${issue.path.join(".") || "$"}: ${issue.message}`).join("\n")
|
|
@@ -19464,47 +19886,47 @@ import path43 from "path";
|
|
|
19464
19886
|
import { existsSync as existsSync31 } from "fs";
|
|
19465
19887
|
import { readdir as readdir3, readFile as readFile29 } from "fs/promises";
|
|
19466
19888
|
import { fileURLToPath } from "url";
|
|
19467
|
-
import { z as
|
|
19889
|
+
import { z as z11 } from "zod";
|
|
19468
19890
|
var SHA256_RE2 = /^[0-9a-f]{64}$/;
|
|
19469
19891
|
var RECIPE_ID_RE = /^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/;
|
|
19470
19892
|
var VERSION_RE = /^\d+\.\d+\.\d+$/;
|
|
19471
19893
|
var RECIPE_FILE = "pixelkiln.recipe.json";
|
|
19472
19894
|
var RECIPE_DIR_TOKEN = "{{recipeDir}}";
|
|
19473
|
-
var PortablePathSchema =
|
|
19895
|
+
var PortablePathSchema = z11.string().min(1).refine((value) => {
|
|
19474
19896
|
if (value.includes("\\") || path43.posix.isAbsolute(value)) return false;
|
|
19475
19897
|
const parts = value.split("/");
|
|
19476
19898
|
return !parts.includes("") && !parts.includes(".") && !parts.includes("..");
|
|
19477
19899
|
}, "expected a portable relative path without '.', '..', or backslashes");
|
|
19478
|
-
var RecipeBindingSchema =
|
|
19479
|
-
nodeId:
|
|
19480
|
-
input:
|
|
19900
|
+
var RecipeBindingSchema = z11.object({
|
|
19901
|
+
nodeId: z11.string().min(1),
|
|
19902
|
+
input: z11.string().min(1)
|
|
19481
19903
|
}).strict();
|
|
19482
|
-
var RecipeSchema =
|
|
19483
|
-
$schema:
|
|
19484
|
-
format:
|
|
19485
|
-
schemaVersion:
|
|
19486
|
-
id:
|
|
19487
|
-
version:
|
|
19488
|
-
provider:
|
|
19489
|
-
summary:
|
|
19490
|
-
files:
|
|
19904
|
+
var RecipeSchema = z11.object({
|
|
19905
|
+
$schema: z11.string().url().optional(),
|
|
19906
|
+
format: z11.literal("pixelkiln-recipe"),
|
|
19907
|
+
schemaVersion: z11.literal(1),
|
|
19908
|
+
id: z11.string().regex(RECIPE_ID_RE, "expected provider/name"),
|
|
19909
|
+
version: z11.string().regex(VERSION_RE, "expected x.y.z"),
|
|
19910
|
+
provider: z11.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
19911
|
+
summary: z11.string().min(1).max(240),
|
|
19912
|
+
files: z11.array(z11.object({
|
|
19491
19913
|
path: PortablePathSchema,
|
|
19492
|
-
role:
|
|
19493
|
-
sha256:
|
|
19914
|
+
role: z11.enum(["workflow", "reference"]),
|
|
19915
|
+
sha256: z11.string().regex(SHA256_RE2)
|
|
19494
19916
|
}).strict()).default([]),
|
|
19495
|
-
models:
|
|
19917
|
+
models: z11.array(z11.object({
|
|
19496
19918
|
path: PortablePathSchema,
|
|
19497
|
-
sha256:
|
|
19498
|
-
source:
|
|
19499
|
-
license:
|
|
19919
|
+
sha256: z11.string().regex(SHA256_RE2),
|
|
19920
|
+
source: z11.string().url(),
|
|
19921
|
+
license: z11.string().min(1)
|
|
19500
19922
|
}).strict()).default([]),
|
|
19501
|
-
styleId:
|
|
19923
|
+
styleId: z11.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
19502
19924
|
style: StyleSchema,
|
|
19503
|
-
workflow:
|
|
19925
|
+
workflow: z11.object({
|
|
19504
19926
|
path: PortablePathSchema,
|
|
19505
|
-
outputNodeId:
|
|
19506
|
-
numImages:
|
|
19507
|
-
bindings:
|
|
19927
|
+
outputNodeId: z11.string().min(1),
|
|
19928
|
+
numImages: z11.number().int().min(1).max(16),
|
|
19929
|
+
bindings: z11.object({
|
|
19508
19930
|
prompt: RecipeBindingSchema,
|
|
19509
19931
|
width: RecipeBindingSchema.optional(),
|
|
19510
19932
|
height: RecipeBindingSchema.optional(),
|
|
@@ -19515,67 +19937,67 @@ var RecipeSchema = z10.object({
|
|
|
19515
19937
|
strength: RecipeBindingSchema.optional()
|
|
19516
19938
|
}).strict()
|
|
19517
19939
|
}).strict().optional(),
|
|
19518
|
-
quality:
|
|
19519
|
-
stage:
|
|
19520
|
-
workingCanvas:
|
|
19521
|
-
width:
|
|
19522
|
-
height:
|
|
19940
|
+
quality: z11.object({
|
|
19941
|
+
stage: z11.enum(["composition-source", "production-candidate"]),
|
|
19942
|
+
workingCanvas: z11.object({
|
|
19943
|
+
width: z11.number().int().min(16),
|
|
19944
|
+
height: z11.number().int().min(16)
|
|
19523
19945
|
}).strict(),
|
|
19524
|
-
recommendedNativeSize:
|
|
19525
|
-
min:
|
|
19526
|
-
max:
|
|
19946
|
+
recommendedNativeSize: z11.object({
|
|
19947
|
+
min: z11.number().int().min(1),
|
|
19948
|
+
max: z11.number().int().min(1)
|
|
19527
19949
|
}).strict(),
|
|
19528
|
-
paletteColors:
|
|
19529
|
-
min:
|
|
19530
|
-
max:
|
|
19950
|
+
paletteColors: z11.object({
|
|
19951
|
+
min: z11.number().int().min(1),
|
|
19952
|
+
max: z11.number().int().min(1)
|
|
19531
19953
|
}).strict(),
|
|
19532
|
-
background:
|
|
19533
|
-
checks:
|
|
19954
|
+
background: z11.enum(["opaque", "transparent", "full-bleed"]),
|
|
19955
|
+
checks: z11.array(z11.enum([
|
|
19534
19956
|
"prompt-coverage",
|
|
19535
19957
|
"native-grid",
|
|
19536
19958
|
"final-palette",
|
|
19537
19959
|
"alpha-edge",
|
|
19538
19960
|
"human-1x"
|
|
19539
19961
|
])).min(1),
|
|
19540
|
-
notes:
|
|
19962
|
+
notes: z11.array(z11.string().min(1)).default([])
|
|
19541
19963
|
}).strict(),
|
|
19542
|
-
integrity:
|
|
19543
|
-
algorithm:
|
|
19544
|
-
digest:
|
|
19964
|
+
integrity: z11.object({
|
|
19965
|
+
algorithm: z11.literal("sha256"),
|
|
19966
|
+
digest: z11.string().regex(SHA256_RE2)
|
|
19545
19967
|
}).strict()
|
|
19546
19968
|
}).strict().superRefine((recipe, context) => {
|
|
19547
19969
|
if (recipe.style.provider && recipe.style.provider !== recipe.provider) {
|
|
19548
19970
|
context.addIssue({
|
|
19549
|
-
code:
|
|
19971
|
+
code: z11.ZodIssueCode.custom,
|
|
19550
19972
|
path: ["style", "provider"],
|
|
19551
19973
|
message: "must match the recipe provider"
|
|
19552
19974
|
});
|
|
19553
19975
|
}
|
|
19554
19976
|
const filePaths = recipe.files.map((file) => file.path);
|
|
19555
19977
|
if (new Set(filePaths).size !== filePaths.length) {
|
|
19556
|
-
context.addIssue({ code:
|
|
19978
|
+
context.addIssue({ code: z11.ZodIssueCode.custom, path: ["files"], message: "duplicate file path" });
|
|
19557
19979
|
}
|
|
19558
19980
|
const modelPaths = recipe.models.map((model) => model.path);
|
|
19559
19981
|
if (new Set(modelPaths).size !== modelPaths.length) {
|
|
19560
|
-
context.addIssue({ code:
|
|
19982
|
+
context.addIssue({ code: z11.ZodIssueCode.custom, path: ["models"], message: "duplicate model path" });
|
|
19561
19983
|
}
|
|
19562
19984
|
if (filePaths.includes(RECIPE_FILE)) {
|
|
19563
19985
|
context.addIssue({
|
|
19564
|
-
code:
|
|
19986
|
+
code: z11.ZodIssueCode.custom,
|
|
19565
19987
|
path: ["files"],
|
|
19566
19988
|
message: `${RECIPE_FILE} cannot hash itself`
|
|
19567
19989
|
});
|
|
19568
19990
|
}
|
|
19569
19991
|
if (recipe.quality.recommendedNativeSize.min > recipe.quality.recommendedNativeSize.max) {
|
|
19570
19992
|
context.addIssue({
|
|
19571
|
-
code:
|
|
19993
|
+
code: z11.ZodIssueCode.custom,
|
|
19572
19994
|
path: ["quality", "recommendedNativeSize"],
|
|
19573
19995
|
message: "min cannot exceed max"
|
|
19574
19996
|
});
|
|
19575
19997
|
}
|
|
19576
19998
|
if (recipe.quality.paletteColors.min > recipe.quality.paletteColors.max) {
|
|
19577
19999
|
context.addIssue({
|
|
19578
|
-
code:
|
|
20000
|
+
code: z11.ZodIssueCode.custom,
|
|
19579
20001
|
path: ["quality", "paletteColors"],
|
|
19580
20002
|
message: "min cannot exceed max"
|
|
19581
20003
|
});
|
|
@@ -19584,7 +20006,7 @@ var RecipeSchema = z10.object({
|
|
|
19584
20006
|
(file) => file.path === recipe.workflow.path && file.role === "workflow"
|
|
19585
20007
|
)) {
|
|
19586
20008
|
context.addIssue({
|
|
19587
|
-
code:
|
|
20009
|
+
code: z11.ZodIssueCode.custom,
|
|
19588
20010
|
path: ["workflow", "path"],
|
|
19589
20011
|
message: "must name a file whose role is workflow"
|
|
19590
20012
|
});
|
|
@@ -19592,7 +20014,7 @@ var RecipeSchema = z10.object({
|
|
|
19592
20014
|
if (recipe.provider === "comfyui") {
|
|
19593
20015
|
if (!recipe.workflow) {
|
|
19594
20016
|
context.addIssue({
|
|
19595
|
-
code:
|
|
20017
|
+
code: z11.ZodIssueCode.custom,
|
|
19596
20018
|
path: ["workflow"],
|
|
19597
20019
|
message: "ComfyUI recipes require workflow metadata"
|
|
19598
20020
|
});
|
|
@@ -19601,7 +20023,7 @@ var RecipeSchema = z10.object({
|
|
|
19601
20023
|
const options = recipe.style.providerOptions.comfyui;
|
|
19602
20024
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
19603
20025
|
context.addIssue({
|
|
19604
|
-
code:
|
|
20026
|
+
code: z11.ZodIssueCode.custom,
|
|
19605
20027
|
path: ["style", "providerOptions", "comfyui"],
|
|
19606
20028
|
message: "ComfyUI recipes require ComfyUI provider options"
|
|
19607
20029
|
});
|
|
@@ -19615,7 +20037,7 @@ var RecipeSchema = z10.object({
|
|
|
19615
20037
|
};
|
|
19616
20038
|
if (JSON.stringify(canonical3(options)) !== JSON.stringify(canonical3(expected))) {
|
|
19617
20039
|
context.addIssue({
|
|
19618
|
-
code:
|
|
20040
|
+
code: z11.ZodIssueCode.custom,
|
|
19619
20041
|
path: ["style", "providerOptions", "comfyui"],
|
|
19620
20042
|
message: "must match workflow metadata and use {{recipeDir}} for workflowFile"
|
|
19621
20043
|
});
|
|
@@ -20034,6 +20456,30 @@ async function runRefine(args) {
|
|
|
20034
20456
|
if (result.failed) process.exitCode = 1;
|
|
20035
20457
|
}
|
|
20036
20458
|
|
|
20459
|
+
// src/cli/commands/skeleton.ts
|
|
20460
|
+
import path46 from "path";
|
|
20461
|
+
import { readFile as readFile30, writeFile as writeFile15 } from "fs/promises";
|
|
20462
|
+
async function runEstimateSkeleton(args) {
|
|
20463
|
+
const image = args.target;
|
|
20464
|
+
if (!image) throw new UsageError("estimate-skeleton needs an image path: pixelkiln estimate-skeleton <image> [--out keypoints.json]");
|
|
20465
|
+
loadEnvFiles(path46.dirname(path46.resolve(args.manifest)));
|
|
20466
|
+
loadEnvFiles(process.cwd());
|
|
20467
|
+
const bytes = await readFile30(path46.resolve(image));
|
|
20468
|
+
const metadata = imageMetadata(bytes);
|
|
20469
|
+
if (!metadata) throw new UsageError(`${image} is not a readable PNG or JPEG`);
|
|
20470
|
+
const client2 = clientFromEnv();
|
|
20471
|
+
const res = await client2.estimateSkeleton({
|
|
20472
|
+
image: { base64: bytes.toString("base64"), format: metadata.format }
|
|
20473
|
+
});
|
|
20474
|
+
const json = JSON.stringify(res.keypoints, null, 2);
|
|
20475
|
+
if (args.out) {
|
|
20476
|
+
await writeFile15(path46.resolve(args.out), json + "\n");
|
|
20477
|
+
log(` wrote ${res.keypoints.length} keypoints to ${args.out}`);
|
|
20478
|
+
} else {
|
|
20479
|
+
log(json);
|
|
20480
|
+
}
|
|
20481
|
+
}
|
|
20482
|
+
|
|
20037
20483
|
// src/cli/commands/tools.ts
|
|
20038
20484
|
async function runTools(args) {
|
|
20039
20485
|
const mb = (bytes) => bytes < 1e6 ? `${(bytes / 1e3).toFixed(0)} kB` : `${(bytes / 1e6).toFixed(1)} MB`;
|
|
@@ -20076,15 +20522,15 @@ async function runTools(args) {
|
|
|
20076
20522
|
}
|
|
20077
20523
|
|
|
20078
20524
|
// src/cli/commands/workspace.ts
|
|
20079
|
-
import
|
|
20525
|
+
import path47 from "path";
|
|
20080
20526
|
import { existsSync as existsSync32 } from "fs";
|
|
20081
20527
|
async function runWorkspace(args) {
|
|
20082
|
-
const workspacePath =
|
|
20083
|
-
const dir =
|
|
20528
|
+
const workspacePath = path47.resolve(args.workspace ?? "pixelkiln.workspace.json");
|
|
20529
|
+
const dir = path47.dirname(workspacePath);
|
|
20084
20530
|
if (args.subcommand === "add") {
|
|
20085
|
-
const manifestPath =
|
|
20531
|
+
const manifestPath = path47.resolve(args.target);
|
|
20086
20532
|
const loadedTarget = await loadManifest(manifestPath);
|
|
20087
|
-
const lockPath = args.explicitLock ?
|
|
20533
|
+
const lockPath = args.explicitLock ? path47.resolve(args.explicitLock) : path47.join(path47.dirname(manifestPath), "pixelkiln.lock.json");
|
|
20088
20534
|
const ws = await loadWorkspace(workspacePath);
|
|
20089
20535
|
const id = args.name ?? loadedTarget.manifest.name;
|
|
20090
20536
|
if (ws.projects.some((p) => p.id === id)) {
|
|
@@ -20104,7 +20550,7 @@ async function runWorkspace(args) {
|
|
|
20104
20550
|
...args.account ? { account: args.account } : {}
|
|
20105
20551
|
};
|
|
20106
20552
|
await saveWorkspace(workspacePath, { version: 1, projects: [...ws.projects, project] });
|
|
20107
|
-
log(` registered "${id}" in ${
|
|
20553
|
+
log(` registered "${id}" in ${path47.relative(process.cwd(), workspacePath)}`);
|
|
20108
20554
|
log(` manifest: ${project.manifest}`);
|
|
20109
20555
|
log(` lock: ${project.lock}`);
|
|
20110
20556
|
if (!existsSync32(lockPath)) {
|
|
@@ -20116,7 +20562,7 @@ async function runWorkspace(args) {
|
|
|
20116
20562
|
}
|
|
20117
20563
|
if (args.subcommand === "remove") {
|
|
20118
20564
|
const ws = await loadWorkspace(workspacePath);
|
|
20119
|
-
const resolvedTarget =
|
|
20565
|
+
const resolvedTarget = path47.resolve(args.target);
|
|
20120
20566
|
const match = ws.projects.find(
|
|
20121
20567
|
(p) => p.id === args.target || resolveProject(dir, p).manifestPath === resolvedTarget
|
|
20122
20568
|
);
|
|
@@ -20127,7 +20573,7 @@ async function runWorkspace(args) {
|
|
|
20127
20573
|
version: 1,
|
|
20128
20574
|
projects: ws.projects.filter((p) => p !== match)
|
|
20129
20575
|
});
|
|
20130
|
-
log(` removed "${match.id}" from ${
|
|
20576
|
+
log(` removed "${match.id}" from ${path47.relative(process.cwd(), workspacePath)}`);
|
|
20131
20577
|
return;
|
|
20132
20578
|
}
|
|
20133
20579
|
if (args.subcommand === "list") {
|
|
@@ -20139,9 +20585,9 @@ async function runWorkspace(args) {
|
|
|
20139
20585
|
if (args.json) {
|
|
20140
20586
|
log(JSON.stringify({ version: 1, workspace: workspacePath, projects: ws.projects, diagnostics }, null, 2));
|
|
20141
20587
|
} else if (!ws.projects.length) {
|
|
20142
|
-
log(` no projects registered in ${
|
|
20588
|
+
log(` no projects registered in ${path47.relative(process.cwd(), workspacePath)}`);
|
|
20143
20589
|
} else {
|
|
20144
|
-
log(` ${ws.projects.length} project(s) in ${
|
|
20590
|
+
log(` ${ws.projects.length} project(s) in ${path47.relative(process.cwd(), workspacePath)}:`);
|
|
20145
20591
|
for (const p of ws.projects) {
|
|
20146
20592
|
log(` ${p.id.padEnd(24)} ${p.manifest.padEnd(40)} (${p.provider}${p.account ? `, ${p.account}` : ""})`);
|
|
20147
20593
|
}
|
|
@@ -20159,7 +20605,7 @@ async function runWorkspace(args) {
|
|
|
20159
20605
|
if (args.json) {
|
|
20160
20606
|
log(JSON.stringify({ ...report, workspace: workspacePath }, null, 2));
|
|
20161
20607
|
} else {
|
|
20162
|
-
log(` workspace: ${
|
|
20608
|
+
log(` workspace: ${path47.relative(process.cwd(), workspacePath)}`);
|
|
20163
20609
|
for (const p of report.projects) {
|
|
20164
20610
|
if (p.error) {
|
|
20165
20611
|
log(`
|
|
@@ -20214,7 +20660,7 @@ async function runVersion() {
|
|
|
20214
20660
|
for (const up of ["../package.json", "../../package.json"]) {
|
|
20215
20661
|
const url = new URL(up, import.meta.url);
|
|
20216
20662
|
if (!existsSync33(url)) continue;
|
|
20217
|
-
const pkg = JSON.parse(await
|
|
20663
|
+
const pkg = JSON.parse(await readFile31(url, "utf8"));
|
|
20218
20664
|
if (pkg.name === "pixelkiln") {
|
|
20219
20665
|
log(`${pkg.name} ${pkg.version}`);
|
|
20220
20666
|
return;
|
|
@@ -20258,6 +20704,7 @@ var RUNNERS = {
|
|
|
20258
20704
|
refine: runRefine,
|
|
20259
20705
|
recipe: runRecipe,
|
|
20260
20706
|
workspace: runWorkspace,
|
|
20707
|
+
"estimate-skeleton": runEstimateSkeleton,
|
|
20261
20708
|
unzoom: runUnzoom,
|
|
20262
20709
|
font: runFont
|
|
20263
20710
|
};
|