pixelkiln 0.59.0 → 0.60.1
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 +174 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +178 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1030 -135
- package/dist/index.d.ts +1030 -135
- package/dist/index.js +176 -6
- package/dist/index.js.map +1 -1
- package/docs/CHARACTERS.md +8 -2
- package/docs/ENDPOINTS.md +68 -5
- package/docs/GENERATORS.md +46 -0
- package/docs/MANIFEST.md +3 -1
- package/docs/PIXELLAB.md +5 -0
- package/docs/README.md +0 -1
- package/docs/REVISIONS.md +12 -0
- package/package.json +1 -2
- package/schema/manifest.schema.json +156 -2
- package/schema/recipe.schema.json +6 -1
- package/skills/pixelkiln/references/pixellab-roadmap.md +150 -21
- package/skills/pixelkiln/references/pixellab.md +76 -1
- package/skills/pixelkiln/references/revisions.md +6 -1
- package/NAMING.md +0 -87
package/dist/index.cjs
CHANGED
|
@@ -97,6 +97,8 @@ __export(index_exports, {
|
|
|
97
97
|
ScenarioProvider: () => ScenarioProvider,
|
|
98
98
|
StyleInputSchema: () => StyleInputSchema,
|
|
99
99
|
StyleSchema: () => StyleSchema,
|
|
100
|
+
UiElementSchema: () => UiElementSchema,
|
|
101
|
+
UiPieceSchema: () => UiPieceSchema,
|
|
100
102
|
UnsupportedCapabilityError: () => UnsupportedCapabilityError,
|
|
101
103
|
UsageError: () => UsageError,
|
|
102
104
|
WorkspaceProjectSchema: () => WorkspaceProjectSchema,
|
|
@@ -306,7 +308,7 @@ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
|
306
308
|
// src/types.ts
|
|
307
309
|
var import_zod = require("zod");
|
|
308
310
|
var MediaTypeSchema = import_zod.z.enum(["image/png", "image/gif"]);
|
|
309
|
-
var GeneratorSchema = import_zod.z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro"]);
|
|
311
|
+
var GeneratorSchema = import_zod.z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro", "uiAsset"]);
|
|
310
312
|
var GridConfidenceSchema = import_zod.z.enum(["low", "medium", "high"]);
|
|
311
313
|
var RevisionModeSchema = import_zod.z.enum([
|
|
312
314
|
"image-to-image",
|
|
@@ -428,6 +430,50 @@ var CharacterProportionsSchema = import_zod.z.union([
|
|
|
428
430
|
}).strict()
|
|
429
431
|
]);
|
|
430
432
|
var CharacterAnimationModeSchema = import_zod.z.enum(["template", "v3", "pro"]);
|
|
433
|
+
var UiPieceSchema = import_zod.z.discriminatedUnion("kind", [
|
|
434
|
+
import_zod.z.object({
|
|
435
|
+
id: import_zod.z.string().min(1),
|
|
436
|
+
kind: import_zod.z.literal("rounded_rect"),
|
|
437
|
+
label: import_zod.z.string().optional(),
|
|
438
|
+
x: import_zod.z.number(),
|
|
439
|
+
y: import_zod.z.number(),
|
|
440
|
+
w: import_zod.z.number(),
|
|
441
|
+
h: import_zod.z.number(),
|
|
442
|
+
radius: import_zod.z.number().min(0).optional()
|
|
443
|
+
}).strict(),
|
|
444
|
+
import_zod.z.object({
|
|
445
|
+
id: import_zod.z.string().min(1),
|
|
446
|
+
kind: import_zod.z.literal("circle"),
|
|
447
|
+
label: import_zod.z.string().optional(),
|
|
448
|
+
x: import_zod.z.number(),
|
|
449
|
+
y: import_zod.z.number(),
|
|
450
|
+
r: import_zod.z.number()
|
|
451
|
+
}).strict(),
|
|
452
|
+
import_zod.z.object({
|
|
453
|
+
id: import_zod.z.string().min(1),
|
|
454
|
+
kind: import_zod.z.literal("polygon"),
|
|
455
|
+
label: import_zod.z.string().optional(),
|
|
456
|
+
x: import_zod.z.number(),
|
|
457
|
+
y: import_zod.z.number(),
|
|
458
|
+
r: import_zod.z.number(),
|
|
459
|
+
sides: import_zod.z.number().int().min(3),
|
|
460
|
+
phase: import_zod.z.number().optional()
|
|
461
|
+
}).strict()
|
|
462
|
+
]);
|
|
463
|
+
var UiElementSchema = import_zod.z.enum([
|
|
464
|
+
"button",
|
|
465
|
+
"icon_button",
|
|
466
|
+
"toolbar",
|
|
467
|
+
"tab",
|
|
468
|
+
"panel",
|
|
469
|
+
"window",
|
|
470
|
+
"health_bar",
|
|
471
|
+
"avatar",
|
|
472
|
+
"triangle",
|
|
473
|
+
"pentagon",
|
|
474
|
+
"hexagon",
|
|
475
|
+
"octagon"
|
|
476
|
+
]);
|
|
431
477
|
var AssetBatchSchema = import_zod.z.object({
|
|
432
478
|
/** The batch leader: another `1dir` asset in the same style. */
|
|
433
479
|
of: import_zod.z.string().min(1),
|
|
@@ -730,6 +776,12 @@ var StyleObjectSchema = import_zod.z.object({
|
|
|
730
776
|
* in place of `terrainShapeStyle`. The API default is `standard`.
|
|
731
777
|
*/
|
|
732
778
|
terrainMode: import_zod.z.enum(["standard", "pro"]).optional(),
|
|
779
|
+
/**
|
|
780
|
+
* `uiAsset` generator only. A natural-language palette hint sent as-is
|
|
781
|
+
* (e.g. "brown and gold"), distinct from `palette`'s hex-color array —
|
|
782
|
+
* this is a prompt-level steer, not a local quantization target.
|
|
783
|
+
*/
|
|
784
|
+
uiColorPalette: import_zod.z.string().max(200).optional(),
|
|
733
785
|
/**
|
|
734
786
|
* `terrain` generator only, `terrainMode: "standard"`. Procedural
|
|
735
787
|
* boundary geometry: `square` or `round`, 16px or 32px tiles only.
|
|
@@ -1013,6 +1065,10 @@ var AssetSchema = import_zod.z.object({
|
|
|
1013
1065
|
* `AssetBatchSchema`.
|
|
1014
1066
|
*/
|
|
1015
1067
|
batch: AssetBatchSchema.optional(),
|
|
1068
|
+
/** `uiAsset` styles: precise shape regions the panel is composited from. Combine with `elements`; omit both for a default full-canvas panel. */
|
|
1069
|
+
pieces: import_zod.z.array(UiPieceSchema).min(1).optional(),
|
|
1070
|
+
/** `uiAsset` styles: named, auto-positioned UI element scaffolds. Combine with `pieces`; omit both for a default full-canvas panel. */
|
|
1071
|
+
elements: import_zod.z.array(UiElementSchema).min(1).optional(),
|
|
1016
1072
|
/** `character` styles, `standard` humanoid bases: this character's proportions, over the style's. */
|
|
1017
1073
|
proportions: CharacterProportionsSchema.optional(),
|
|
1018
1074
|
/**
|
|
@@ -1530,6 +1586,19 @@ var IsometricTileGetSchema = import_zod2.z.object({
|
|
|
1530
1586
|
image: import_zod2.z.object({ base64: import_zod2.z.string().min(1), format: import_zod2.z.string().default("png") }).passthrough(),
|
|
1531
1587
|
usage: UsageSchema
|
|
1532
1588
|
}).passthrough();
|
|
1589
|
+
var UiAssetSubmitSchema = import_zod2.z.object({
|
|
1590
|
+
ui_asset_id: import_zod2.z.string().min(1),
|
|
1591
|
+
background_job_id: import_zod2.z.string().min(1),
|
|
1592
|
+
status: import_zod2.z.string().default("processing"),
|
|
1593
|
+
usage: UsageSchema
|
|
1594
|
+
}).passthrough();
|
|
1595
|
+
var UiAssetGetSchema = import_zod2.z.object({
|
|
1596
|
+
id: import_zod2.z.string().min(1),
|
|
1597
|
+
status: import_zod2.z.string().nullable().default(null),
|
|
1598
|
+
image_url: import_zod2.z.string().nullable().optional(),
|
|
1599
|
+
progress_percent: import_zod2.z.number().nullable().optional(),
|
|
1600
|
+
eta_seconds: import_zod2.z.number().nullable().optional()
|
|
1601
|
+
}).passthrough();
|
|
1533
1602
|
var RevisionJobSubmitSchema = import_zod2.z.object({
|
|
1534
1603
|
background_job_id: import_zod2.z.string().min(1),
|
|
1535
1604
|
status: import_zod2.z.string().default("processing")
|
|
@@ -1890,6 +1959,48 @@ var PixelLabClient = class {
|
|
|
1890
1959
|
);
|
|
1891
1960
|
return { image: res.image, usage: res.usage ?? null };
|
|
1892
1961
|
}
|
|
1962
|
+
/**
|
|
1963
|
+
* `/create-ui-asset`: one composited panel image from a shape template —
|
|
1964
|
+
* `pieces` (precise rect/circle/polygon regions on a virtual 0–512
|
|
1965
|
+
* editor canvas) and/or named `elements` (auto-positioned scaffolds:
|
|
1966
|
+
* button, icon_button, toolbar, tab, panel, window, health_bar, avatar,
|
|
1967
|
+
* triangle, pentagon, hexagon, octagon), or neither for a default
|
|
1968
|
+
* full-canvas rounded-rect panel. Unlike every other generator here, the
|
|
1969
|
+
* result is one flat image with no per-piece sub-regions or nine-slice
|
|
1970
|
+
* metadata returned — cropping a `pieces` layout into separate files
|
|
1971
|
+
* would be pixelkiln's own local work, not modeled yet.
|
|
1972
|
+
*/
|
|
1973
|
+
async createUiAsset(args) {
|
|
1974
|
+
const body = {
|
|
1975
|
+
description: args.description,
|
|
1976
|
+
image_size: { width: args.width, height: args.height }
|
|
1977
|
+
};
|
|
1978
|
+
if (args.pieces?.length) body.pieces = args.pieces;
|
|
1979
|
+
if (args.elements?.length) body.elements = args.elements;
|
|
1980
|
+
if (args.styleImage) body.style_image = args.styleImage;
|
|
1981
|
+
if (args.colorPalette) body.color_palette = args.colorPalette;
|
|
1982
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
1983
|
+
if (args.seed != null) body.seed = args.seed;
|
|
1984
|
+
const res = await validateResponse(
|
|
1985
|
+
UiAssetSubmitSchema,
|
|
1986
|
+
await this.request("/create-ui-asset", { method: "POST", body: JSON.stringify(body) }),
|
|
1987
|
+
"create ui asset"
|
|
1988
|
+
);
|
|
1989
|
+
return { ui_asset_id: res.ui_asset_id, background_job_id: res.background_job_id, usage: res.usage };
|
|
1990
|
+
}
|
|
1991
|
+
async getUiAsset(uiAssetId) {
|
|
1992
|
+
const res = await validateResponse(
|
|
1993
|
+
UiAssetGetSchema,
|
|
1994
|
+
await this.request(`/ui-assets/${encodeURIComponent(uiAssetId)}`),
|
|
1995
|
+
"get ui asset"
|
|
1996
|
+
);
|
|
1997
|
+
return {
|
|
1998
|
+
status: res.status,
|
|
1999
|
+
imageUrl: res.image_url ?? null,
|
|
2000
|
+
progressPercent: res.progress_percent ?? null,
|
|
2001
|
+
etaSeconds: res.eta_seconds ?? null
|
|
2002
|
+
};
|
|
2003
|
+
}
|
|
1893
2004
|
/**
|
|
1894
2005
|
* Synchronous single-image generation. Returns the PNG inline rather than a
|
|
1895
2006
|
* job id, and is the only endpoint that honours a forced palette;
|
|
@@ -3027,16 +3138,20 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
3027
3138
|
detail: spec.detail ?? null,
|
|
3028
3139
|
seed: spec.seed ?? null,
|
|
3029
3140
|
palette: spec.palette,
|
|
3030
|
-
// `noBackground` only reaches the wire for pixflux; the
|
|
3031
|
-
// undefined for every other generator. `tileSize` is
|
|
3032
|
-
// absent; width/height are derived from it, so it is
|
|
3033
|
-
|
|
3141
|
+
// `noBackground` only reaches the wire for pixflux and uiAsset; the
|
|
3142
|
+
// tile fields are undefined for every other generator. `tileSize` is
|
|
3143
|
+
// intentionally absent; width/height are derived from it, so it is
|
|
3144
|
+
// already covered.
|
|
3145
|
+
noBackground: spec.generator === "pixflux" || spec.generator === "uiAsset" || spec.provider !== "pixellab" ? spec.noBackground : void 0,
|
|
3034
3146
|
tileType: spec.tileType,
|
|
3035
3147
|
tileView: spec.tileView,
|
|
3036
3148
|
tileFeature: spec.tileFeature,
|
|
3037
3149
|
outlineMode: spec.outlineMode,
|
|
3038
3150
|
isometricTileSize: spec.isometricTileSize,
|
|
3039
3151
|
isometricTileShape: spec.isometricTileShape,
|
|
3152
|
+
uiPieces: spec.uiPieces,
|
|
3153
|
+
uiElements: spec.uiElements,
|
|
3154
|
+
uiColorPalette: spec.uiColorPalette,
|
|
3040
3155
|
styleImages: styleImageHashes,
|
|
3041
3156
|
// A character family: the engine and rotations of a base, the parent's
|
|
3042
3157
|
// generated bytes for a state or animation (so a regenerated parent
|
|
@@ -3234,7 +3349,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3234
3349
|
return new _PixelLabProvider(new PixelLabClient("download-only"));
|
|
3235
3350
|
}
|
|
3236
3351
|
supports(generator) {
|
|
3237
|
-
return generator === "1dir" || generator === "map" || generator === "pixflux" || generator === "tiles" || generator === "terrain" || generator === "imagePro" || generator === "character" || generator === "isometricTile" || generator === "objectPro";
|
|
3352
|
+
return generator === "1dir" || generator === "map" || generator === "pixflux" || generator === "tiles" || generator === "terrain" || generator === "imagePro" || generator === "character" || generator === "isometricTile" || generator === "objectPro" || generator === "uiAsset";
|
|
3238
3353
|
}
|
|
3239
3354
|
/**
|
|
3240
3355
|
* `inpaint` (`/inpaint-v3`, a mask) and `image-to-image` (`/edit-images-v2`,
|
|
@@ -3350,6 +3465,11 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3350
3465
|
`PixelLab imagePro is ${spec.width}x${spec.height}; the API takes 16 to 792 wide and 16 to 688 tall (the exact ceiling also depends on aspect ratio)`
|
|
3351
3466
|
);
|
|
3352
3467
|
}
|
|
3468
|
+
if (spec.generator === "uiAsset" && (spec.width < 192 || spec.height < 192 || spec.width > 688 || spec.height > 688)) {
|
|
3469
|
+
throw new Error(
|
|
3470
|
+
`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)`
|
|
3471
|
+
);
|
|
3472
|
+
}
|
|
3353
3473
|
if (spec.generator === "map") {
|
|
3354
3474
|
requirePixelLabOption("map", "view", spec.view, ["low top-down", "high top-down", "side"]);
|
|
3355
3475
|
requirePixelLabOption("map", "outline", spec.outline, [
|
|
@@ -3987,6 +4107,20 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3987
4107
|
if (spec.revision) return this.submitRevision(spec);
|
|
3988
4108
|
if (spec.generator === "character") return this.submitCharacter(spec, styleImages, context);
|
|
3989
4109
|
if (spec.generator === "objectPro") return this.submitObjectPro(spec, styleImages, context);
|
|
4110
|
+
if (spec.generator === "uiAsset") {
|
|
4111
|
+
const res2 = await this.client.createUiAsset({
|
|
4112
|
+
description: spec.prompt,
|
|
4113
|
+
width: spec.width,
|
|
4114
|
+
height: spec.height,
|
|
4115
|
+
pieces: spec.uiPieces,
|
|
4116
|
+
elements: spec.uiElements,
|
|
4117
|
+
styleImage: styleImages[0] ? { base64: styleImages[0].base64, format: styleImages[0].format } : void 0,
|
|
4118
|
+
colorPalette: spec.uiColorPalette,
|
|
4119
|
+
noBackground: spec.noBackground,
|
|
4120
|
+
seed: spec.seed
|
|
4121
|
+
});
|
|
4122
|
+
return { jobId: res2.ui_asset_id, metadata: { backgroundJobId: res2.background_job_id } };
|
|
4123
|
+
}
|
|
3990
4124
|
if (spec.generator === "pixflux") {
|
|
3991
4125
|
const swatch = spec.palette.length ? paletteSwatch(spec.palette).toString("base64") : void 0;
|
|
3992
4126
|
const { png } = await this.client.createImagePixflux({
|
|
@@ -4263,6 +4397,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4263
4397
|
if (generator === "imagePro") return this.pollImagePro(jobId);
|
|
4264
4398
|
if (generator === "character") return this.pollCharacter(jobId, context);
|
|
4265
4399
|
if (generator === "objectPro") return this.pollObjectPro(jobId, context);
|
|
4400
|
+
if (generator === "uiAsset") return this.pollUiAsset(jobId, context);
|
|
4266
4401
|
const backgroundJobId = context?.metadata?.backgroundJobId;
|
|
4267
4402
|
const obj = await this.client.getObject(jobId);
|
|
4268
4403
|
if (obj.status === "review") {
|
|
@@ -4582,6 +4717,29 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4582
4717
|
throw err;
|
|
4583
4718
|
}
|
|
4584
4719
|
}
|
|
4720
|
+
/**
|
|
4721
|
+
* `/ui-assets/{id}` reports progress with its own `status` field
|
|
4722
|
+
* ("processing"/"completed"/"failed") rather than a 423, and its result is
|
|
4723
|
+
* one flat composited image at a hosted `image_url` — no per-piece
|
|
4724
|
+
* sub-images, no nine-slice metadata, confirmed absent from the response
|
|
4725
|
+
* schema. There is nothing to review: one job is one ready image, like
|
|
4726
|
+
* `isometricTile`.
|
|
4727
|
+
*/
|
|
4728
|
+
async pollUiAsset(uiAssetId, context) {
|
|
4729
|
+
const asset = await this.client.getUiAsset(uiAssetId);
|
|
4730
|
+
if (asset.status === "failed") return { status: "failed", error: "UI asset generation failed upstream" };
|
|
4731
|
+
if (asset.status !== "completed" || !asset.imageUrl) {
|
|
4732
|
+
return { status: "processing", progressPercent: asset.progressPercent, etaSeconds: asset.etaSeconds };
|
|
4733
|
+
}
|
|
4734
|
+
const backgroundJobId = context?.metadata?.backgroundJobId;
|
|
4735
|
+
return {
|
|
4736
|
+
status: "ready",
|
|
4737
|
+
objectId: uiAssetId,
|
|
4738
|
+
sourceUrl: asset.imageUrl,
|
|
4739
|
+
sources: [{ url: asset.imageUrl }],
|
|
4740
|
+
billed: await this.billedForJob(backgroundJobId)
|
|
4741
|
+
};
|
|
4742
|
+
}
|
|
4585
4743
|
async selectCandidate(jobId, index, commonTag, generator) {
|
|
4586
4744
|
if (generator === "tiles") {
|
|
4587
4745
|
const set = await this.client.getTilesPro(jobId);
|
|
@@ -7362,6 +7520,10 @@ async function resolveSpecs(loaded, filter) {
|
|
|
7362
7520
|
size = asset.size ?? style.size ?? 64;
|
|
7363
7521
|
width = size;
|
|
7364
7522
|
height = size;
|
|
7523
|
+
} else if (generator === "uiAsset") {
|
|
7524
|
+
width = asset.width ?? style.size ?? 256;
|
|
7525
|
+
height = asset.height ?? style.size ?? 256;
|
|
7526
|
+
size = Math.max(width, height);
|
|
7365
7527
|
} else {
|
|
7366
7528
|
width = asset.width ?? style.size ?? 64;
|
|
7367
7529
|
height = asset.height ?? style.size ?? 64;
|
|
@@ -7372,6 +7534,11 @@ async function resolveSpecs(loaded, filter) {
|
|
|
7372
7534
|
`assets.${assetId}: ${asset.state ? "state" : "animation"} needs a character or objectPro style; "${styleId}" generates ${generator}`
|
|
7373
7535
|
);
|
|
7374
7536
|
}
|
|
7537
|
+
if ((asset.pieces || asset.elements) && generator !== "uiAsset") {
|
|
7538
|
+
throw new Error(
|
|
7539
|
+
`assets.${assetId}: ${asset.pieces ? "pieces" : "elements"} needs a uiAsset style; "${styleId}" generates ${generator}`
|
|
7540
|
+
);
|
|
7541
|
+
}
|
|
7375
7542
|
const characterKind = asset.animation ? "animation" : asset.state ? "state" : "base";
|
|
7376
7543
|
const subject = asset.promptByStyle[styleId] ?? asset.prompt ?? "";
|
|
7377
7544
|
let terrainLowerDescription;
|
|
@@ -7418,6 +7585,9 @@ async function resolveSpecs(loaded, filter) {
|
|
|
7418
7585
|
shading: style.shading,
|
|
7419
7586
|
detail: style.detail,
|
|
7420
7587
|
seed: style.seed,
|
|
7588
|
+
uiPieces: generator === "uiAsset" ? asset.pieces : void 0,
|
|
7589
|
+
uiElements: generator === "uiAsset" ? asset.elements : void 0,
|
|
7590
|
+
uiColorPalette: generator === "uiAsset" ? style.uiColorPalette : void 0,
|
|
7421
7591
|
palette: style.palette,
|
|
7422
7592
|
enforcePalette: style.enforcePalette,
|
|
7423
7593
|
noBackground: style.noBackground,
|
|
@@ -16529,6 +16699,8 @@ async function workspaceStatus(ws, dir) {
|
|
|
16529
16699
|
ScenarioProvider,
|
|
16530
16700
|
StyleInputSchema,
|
|
16531
16701
|
StyleSchema,
|
|
16702
|
+
UiElementSchema,
|
|
16703
|
+
UiPieceSchema,
|
|
16532
16704
|
UnsupportedCapabilityError,
|
|
16533
16705
|
UsageError,
|
|
16534
16706
|
WorkspaceProjectSchema,
|