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.
@@ -120,6 +120,16 @@ is read again at submit time and refused if it changed since `plan`.
120
120
  States, animations, and mirrors take their look from their parent and
121
121
  cannot carry a reference.
122
122
 
123
+ A `pro-flash` base's reference can be an image PixelKiln drew with the
124
+ [`imageProFlash`](./GENERATORS.md#imageproflash) generator: point `reference`
125
+ at that asset's downloaded file. When the file is byte-for-byte the output of
126
+ an `imageProFlash` lock entry, submit sends PixelLab that image's
127
+ `source_image_id` instead of uploading the same pixels, and the character is
128
+ drawn from the exact image PixelLab already holds. The price is the same
129
+ either way (the rotations only); the difference is that nothing is
130
+ re-encoded. Generate and fetch the still before planning the character, so
131
+ the file exists. An `objectPro` base's reference is handled the same way.
132
+
123
133
  ### Concept images and style anchors (pro)
124
134
 
125
135
  The pro engine has two more ways in. `concept` on a base names a concept
package/docs/CLI.md CHANGED
@@ -344,6 +344,23 @@ Show one provider's remaining balance and cost unit. A mixed manifest requires
344
344
  `--provider`; a single-provider manifest infers it. Reports a capability error
345
345
  when an installed provider, such as local ComfyUI, has no balance endpoint.
346
346
 
347
+ ### `estimate-skeleton`
348
+
349
+ ```bash
350
+ pixelkiln estimate-skeleton <image> [--out keypoints.json]
351
+ ```
352
+
353
+ PixelLab only. Derives an 18-joint skeleton from an image via
354
+ `/estimate-skeleton` and prints the keypoints JSON, or writes it with `--out`.
355
+ Same category as `balance`: a direct, un-budgeted account call outside the
356
+ manifest/plan/lock pipeline — no manifest is read beyond locating
357
+ `.env.local`, and nothing is written to a lockfile. This is how to bootstrap
358
+ an `animate-skeleton` revision's `keypointsFile` (see
359
+ [Controlled asset revisions](./REVISIONS.md#skeleton-driven-animation)):
360
+ estimate once, sanity-check the result, hand-tweak a few joints for
361
+ in-between frames, rather than hand-authoring 18 joints of
362
+ `{label, x, y, z_index}` from scratch.
363
+
347
364
  ### `status`
348
365
 
349
366
  Summarize lock entries by state and successful submission spend by cost unit.
@@ -17,6 +17,7 @@ account; [ENDPOINTS.md](./ENDPOINTS.md) contains the detailed experiments.
17
17
  | A character facing 4 or 8 directions, its poses, and its animations | `character` | 1 per base (standard), 20–40 per pose, 1 per template loop | one set of directions, or one ordered loop |
18
18
  | UI chrome — panels, buttons, health bars, toolbars | `uiAsset` | 20 generations (measured once, at 256x192) | 1 composited image |
19
19
  | One UI element from a description, 16px and up, optionally guided by a concept image | `uiElement` | 20–40 generations (unmeasured) | 1 image |
20
+ | A styled still on the Pro Flash model, or the south sprite a Pro Flash character will rotate | `imageProFlash` | 5–9 generations (PixelLab's provisional quote) | 1 image |
20
21
 
21
22
  Start with `map` unless a required capability points elsewhere. Forty `map`
22
23
  re-rolls cost the same as one 64×64 `1dir` call.
@@ -404,6 +405,49 @@ price at an area well above where `1dir`/`tiles` would bill the ceiling.
404
405
  Left as an over-read for `--budget` until a second size is measured; see
405
406
  [ENDPOINTS.md](./ENDPOINTS.md) for the full writeup.
406
407
 
408
+ ## `imageProFlash`
409
+
410
+ `imageProFlash` wraps PixelLab's `/create-image-pro-flash`: one native
411
+ pixel-art image on the Pro Flash model, the same model the `character` and
412
+ `objectPro` `pro-flash` engines draw with, as a plain still. It sits between
413
+ `pixflux`/`map` (1 generation, no style reference) and `imagePro` (a flat 40):
414
+
415
+ ```jsonc
416
+ {
417
+ "styles": {
418
+ "stills": {
419
+ "generator": "imageProFlash",
420
+ "styleImages": [{ "path": "refs/house-style.png" }],
421
+ "styleTraits": { "palette": true, "outline": true, "detail": false, "shading": true },
422
+ "outDir": "art/stills"
423
+ }
424
+ },
425
+ "assets": {
426
+ "knight": { "prompt": "a knight in blue armor, facing the viewer", "width": 64, "height": 64 }
427
+ }
428
+ }
429
+ ```
430
+
431
+ - Sizes run 16 to 256 per side in multiples of 4, and can be non-square.
432
+ PixelLab's native sizes (24, 32, 32×48, 64, 96×64, 96) are its most
433
+ reliable; other sizes are its "custom (beta)" range.
434
+ - One `styleImages` entry is the style image, and `styleTraits` choose what
435
+ it lends (palette, outline, detail, shading; each on by default), the same
436
+ switches a `pro-flash` character base takes. Traits without a style image
437
+ are refused.
438
+ - One call returns one image, recorded straight away. The lock also records
439
+ PixelLab's `image_id` and `source_image_id` for it: a Pro Flash `character`
440
+ or `objectPro` base whose `reference` is this image's downloaded file
441
+ reuses it by that id instead of uploading the same pixels again (see
442
+ [Characters](./CHARACTERS.md#starting-from-your-own-sprite)).
443
+ - **Cost:** 5 generations up to 96px on the longer side, 6 up to 208px, 9
444
+ beyond, from PixelLab's own `/pro-flash/cost` quotes, which PixelLab calls
445
+ provisional. The billed amount on the finished job is what the lock keeps.
446
+
447
+ The same model also edits and inpaints: `"engine": "pro-flash"` on an
448
+ `image-to-image` or `inpaint` revision; see
449
+ [Controlled asset revisions](./REVISIONS.md#pixellab).
450
+
407
451
  ## `uiElement`
408
452
 
409
453
  `uiElement` wraps PixelLab's `/generate-ui-v2` ("Generate UI (Pro)"): one UI
package/docs/MANIFEST.md CHANGED
@@ -116,7 +116,7 @@ One asset using the fields most projects reach for:
116
116
  |---|---|---|
117
117
  | `extends` | style id | Optional parent style. The child inherits resolved settings but must declare its own `outDir`. |
118
118
  | `provider` | top-level default | Provider registry id for this style. Assets cannot override it. |
119
- | `generator` | `map` | `map`, `1dir`, `pixflux`, `tiles`, `terrain`, `isometricTile`, `imagePro`, `character`, `objectPro`, `uiAsset`, `uiElement`, or provider-specific `animation`/`frames`. See [GENERATORS.md](./GENERATORS.md). |
119
+ | `generator` | `map` | `map`, `1dir`, `pixflux`, `tiles`, `terrain`, `isometricTile`, `imagePro`, `character`, `objectPro`, `uiAsset`, `uiElement`, `imageProFlash`, or provider-specific `animation`/`frames`. See [GENERATORS.md](./GENERATORS.md). |
120
120
  | `outDir` | string, required | Output directory relative to the manifest. |
121
121
  | `promptPrefix` | `""` | Prepended to every participating asset prompt. |
122
122
  | `promptSuffix` | `""` | Appended to every participating asset prompt. |
@@ -144,7 +144,7 @@ One asset using the fields most projects reach for:
144
144
  | `isometric` | `false` | `character` only. Draw `standard` bases and every loop in isometric view. |
145
145
  | `enhancePrompt` | `false` | `character` only, `v3` bases. Let PixelLab expand the prompt into a fuller one before drawing. |
146
146
  | `styleCharacter` | | `character` only, `pro` bases. The asset id of a generated 8-direction character in this style whose look bases drawn from text or a concept follow. An asset may override it. |
147
- | `styleTraits` | all true | `character` only, `pro-flash` bases with a style image. `{ palette, outline, detail, shading }` booleans: which traits the style image lends. |
147
+ | `styleTraits` | all true | `character` `pro-flash` bases and `imageProFlash` styles, with a style image. `{ palette, outline, detail, shading }` booleans: which traits the style image lends. |
148
148
  | `mount` | object | Stable-cell sheet placement; documented below. |
149
149
  | `quality` | object | Optional native-grid, final-palette, and human-approval contract; documented below. |
150
150
  | `tags` | string array, `[]` | Tags inherited by every generated provider object in the style. |
@@ -468,7 +468,7 @@ their own page: [Characters](./CHARACTERS.md) and
468
468
 
469
469
  | Revision field | Type | Meaning |
470
470
  |---|---|---|
471
- | `mode` | enum, required | `image-to-image`, `inpaint`, `outpaint`, `reduce-colors`, `correct-pixelart`, `animate`, `animate-pixminimax`, `interpolate`, or `edit-animation`. The selected provider must opt into the mode. |
471
+ | `mode` | enum, required | `image-to-image`, `inpaint`, `outpaint`, `reduce-colors`, `correct-pixelart`, `animate`, `animate-pixminimax`, `animate-skeleton`, `interpolate`, or `edit-animation`. The selected provider must opt into the mode. |
472
472
  | `from` | asset id, required | Parent asset in the same style. Self-references, unknown ids, and cycles are rejected. A parent written as a set (a character's directions, an animation's frames) is read as every member: `reduce-colors`, `correct-pixelart`, and `edit-animation` take the whole set in one call; the other modes refuse it. See [Revising a whole set at once](./REVISIONS.md#revising-a-whole-set-at-once). |
473
473
  | `mask` | string | Manifest-relative PNG required for `inpaint`; rejected for the other modes. Its dimensions must match an available source. |
474
474
  | `strength` | number 0–1 | Workflow edit/denoise strength (`image-to-image`, `correct-pixelart`); rejected for `reduce-colors`, `animate`, `animate-pixminimax`, `interpolate`, and `edit-animation`. Interpretation is provider- and model-specific. |
@@ -476,11 +476,15 @@ their own page: [Characters](./CHARACTERS.md) and
476
476
  | `paletteImage` | string | `reduce-colors` only. Manifest-relative image whose colors become the palette; unlike `mask`, no size relationship to the source is required. |
477
477
  | `dithering` | enum | `reduce-colors` only. `none` (default), `2x2`, `4x4`, or `8x8`. |
478
478
  | `ditheringStrength` | number 0–10 | `reduce-colors` only. Ignored when `dithering` is `none`. |
479
- | `frames` | integer 4–40, even | `animate`/`animate-pixminimax` only. `animate` caps at 16; `animate-pixminimax` allows up to 40. |
479
+ | `frames` | integer 4–40, even | `animate`/`animate-pixminimax` only. `animate` caps at 16; `animate-pixminimax` allows up to 40. Rejected for `animate-skeleton` (frame count comes from `keypointsFile` instead), `interpolate`, and `edit-animation`. |
480
480
  | `fps` | integer 1–60 | `animate`/`animate-pixminimax`/`interpolate`/`edit-animation` only. Playback rate recorded with the frames; the provider does not store one. Defaults to the parent's own rate when it is a loop, else 8. |
481
481
  | `lastFrame` | string | `animate`/`animate-pixminimax`: manifest-relative image pinning where the motion ends, turning an open-ended animation into an interpolation. `interpolate`: required, the ending keyframe (the parent is the start); it must match the parent's size. |
482
- | `direction` | enum | `animate-pixminimax` only. The sprite's facing, used only alongside `enhancePrompt`. |
482
+ | `direction` | enum | `animate-pixminimax`/`animate-skeleton`. Optional (alongside `enhancePrompt`) for the former; **required** for the latter. |
483
483
  | `enhancePrompt` | boolean | `animate`/`animate-pixminimax` only. Lets the provider expand the prompt into a fuller motion description first, for an extra documented +0.05-generation surcharge. |
484
+ | `keypointsFile` | string, required for `animate-skeleton` | Manifest-relative JSON file (`src/skeleton.ts`'s `SkeletonSetSchema`): the pose the source is already in, plus 3–15 per-frame poses. See [Skeleton-driven animation](./REVISIONS.md#skeleton-driven-animation). |
485
+ | `skeletonTemplate` | string | `animate-skeleton` only. Body a joint's missing `depth` is taken from: `mannequin` (default), `bear`, `cat`, `dog`, `horse`, or `lion`. |
486
+ | `description` | string | `animate-skeleton` only. What the subject *looks like* (colours, clothing, held items) — the asset's own `prompt` is sent as the motion's short label instead. |
487
+ | `engine` | enum | `image-to-image`/`inpaint` only. `pro-flash` draws the edit with PixelLab's Pro Flash edit or inpaint endpoint instead of the default Pro one: 5–9 generations instead of 20–40, 32 to 256px per side in multiples of 4, no `strength`. Omit for the default. |
484
488
 
485
489
  The parent may use committed `source`, downloaded generated output, or a
486
490
  current approved quality output. Parent and mask hashes participate in the
package/docs/PIXELLAB.md CHANGED
@@ -156,20 +156,21 @@ comparing notes with someone using a different one:
156
156
 
157
157
  ## What is outside this adapter
158
158
 
159
- PixelLab offers more than PixelKiln currently exposes. Lip-sync and
160
- skeleton-driven animation are not part of this adapter. Characters, their
161
- states, their animations, their portraits, and outfit transfer onto their
162
- loops are the `character` generator, with all four creation engines
163
- (standard, v3, pro, pro-flash),
164
- reference sprites, concept images, style anchors, mirrors, and every
165
- `animate-character` control; see [Characters](./CHARACTERS.md). Masked
166
- inpainting and whole-image editing are the `revision` asset shape, not the
167
- `character` generator; see [Controlled asset revisions](./REVISIONS.md).
168
- The same revision shape animates, interpolates, recolors, and cleans up any
169
- asset, a whole character or loop at once where the endpoint takes a set.
170
- Object Creator is the `objectPro` generator, UI panels and elements are
171
- `uiAsset` and `uiElement`, and fonts and unzooming reference art are the
172
- standalone `pixelkiln font` and `pixelkiln unzoom` commands. Map Workshop
159
+ PixelLab offers more than PixelKiln currently exposes. Lip-sync and vocal
160
+ animation are not part of this adapter. Characters, their states, their
161
+ animations, their portraits, and outfit transfer onto their loops are the
162
+ `character` generator, with all four creation engines (standard, v3, pro,
163
+ pro-flash), reference sprites, concept images, style anchors, mirrors, and
164
+ every `animate-character` control; see [Characters](./CHARACTERS.md). Masked
165
+ inpainting, whole-image editing, and skeleton-driven animation (posing a
166
+ reference image frame-by-frame from a supplied keypoint skeleton, not a text
167
+ description) are the `revision` asset shape, not the `character` generator;
168
+ see [Controlled asset revisions](./REVISIONS.md). The same revision shape
169
+ animates, interpolates, recolors, and cleans up any asset, a whole character
170
+ or loop at once where the endpoint takes a set. Object Creator is the
171
+ `objectPro` generator, UI panels and elements are `uiAsset` and `uiElement`,
172
+ and fonts and unzooming reference art are the standalone `pixelkiln font` and
173
+ `pixelkiln unzoom` commands. Map Workshop
173
174
  scene composition (placing objects and characters into a map, in-scene
174
175
  inpainting, export) is a separate PixelLab product surface this adapter does
175
176
  not model at all — including PixelKiln's own `map` generator, which is
package/docs/REVISIONS.md CHANGED
@@ -7,11 +7,12 @@ dependencies before submission, and records the lineage in the lockfile.
7
7
 
8
8
  The manifest and pipeline are provider-neutral. ComfyUI and PixelLab implement
9
9
  it; PixelLab covers `image-to-image`, `inpaint`, `reduce-colors`,
10
- `correct-pixelart`, `animate`, `animate-pixminimax`, `interpolate`, and
11
- `edit-animation`, not `outpaint` (its API has no canvas-expansion endpoint).
12
- ComfyUI covers every mode generically except the four frame-set modes
13
- (`animate`, `animate-pixminimax`, `interpolate`, `edit-animation`), which need
14
- an ordered frame set its revision path cannot produce. Retro Diffusion and Scenario reject revision
10
+ `correct-pixelart`, `animate`, `animate-pixminimax`, `animate-skeleton`,
11
+ `interpolate`, and `edit-animation`, not `outpaint` (its API has no
12
+ canvas-expansion endpoint). ComfyUI covers every mode generically except the
13
+ five frame-set modes (`animate`, `animate-pixminimax`, `animate-skeleton`,
14
+ `interpolate`, `edit-animation`), which need an ordered frame set its
15
+ revision path cannot produce. Retro Diffusion and Scenario reject revision
15
16
  work during offline resolution instead of silently starting a fresh
16
17
  text-to-image job.
17
18
 
@@ -316,6 +317,81 @@ writes a single output image, and an animation is a frame set — a structural
316
317
  gap rather than a missing binding, so `supportsRevision` refuses it up front
317
318
  rather than failing partway through submission.
318
319
 
320
+ ## Skeleton-driven animation
321
+
322
+ A third mode, `animate-skeleton`, poses the source image frame-by-frame from
323
+ a supplied 18-joint skeleton per frame instead of a text motion description:
324
+
325
+ ```jsonc
326
+ {
327
+ "assets": {
328
+ "hero-swing": {
329
+ "prompt": "swinging the sword downward",
330
+ "revision": {
331
+ "mode": "animate-skeleton",
332
+ "from": "hero-idle",
333
+ "keypointsFile": "poses/hero-swing.json",
334
+ "direction": "south"
335
+ }
336
+ }
337
+ }
338
+ }
339
+ ```
340
+
341
+ `keypointsFile` names a manifest-relative committed JSON file, not inline
342
+ manifest data — the same reasoning `mask`/`lastFrame` are files rather than
343
+ inline pixels. It must match the shape `src/skeleton.ts`'s `SkeletonSetSchema`
344
+ validates: `{"firstFrameKeypoints": [...18 joints], "frames": [[...18
345
+ joints], ...3 to 15 of them]}`, each joint `{"label": "RIGHT KNEE", "x": 0.52,
346
+ "y": 0.71, "z_index": 9, "depth": 4}` (`depth` optional — PixelLab fills it
347
+ from `skeletonTemplate`, default `mannequin`, when omitted). Bootstrap this
348
+ file with `pixelkiln estimate-skeleton <image> --out poses/hero-swing.json`
349
+ (see [CLI reference](./CLI.md#estimate-skeleton)) rather than hand-typing 18
350
+ joints from scratch, then hand-tweak individual joints for in-between frames.
351
+
352
+ `direction` is **required** for this mode (unlike `animate-pixminimax`,
353
+ where it is optional). `frames`/`fps`/`lastFrame`/`enhancePrompt` are all
354
+ rejected — the frame count comes from the keypoints file itself
355
+ (`frames.length`), never a manifest number. `description` (optional: what the
356
+ character *looks like* — colours, clothing, held items) is a new field
357
+ distinct from the asset's own `prompt`, which this mode sends as the motion's
358
+ short label (PixelLab's `action`) — the same `prompt`-as-motion convention
359
+ `animate`/`animate-pixminimax` already use, just under this endpoint's own
360
+ field name.
361
+
362
+ `firstFrameKeypoints` (inside the keypoints file) describes the pose the
363
+ reference image is *already* in — PixelLab redraws that frame first to learn
364
+ its background and colors before animating forward, and does not return it.
365
+ **PixelKiln cannot verify this against the image's actual content.** A
366
+ mismatch does not error; it silently degrades transparency and color
367
+ accuracy in every generated frame. When in doubt, run `estimate-skeleton` on
368
+ the reference image itself and use that result, rather than hand-authoring
369
+ a guess.
370
+
371
+ **Deliberately not wired into the manifest pipeline: `estimate-skeleton`
372
+ itself.** `PixelLabClient.estimateSkeleton()` exists and the CLI command above
373
+ calls it directly, but nothing in `resolveSpecs`/`estimate()`/`submitRevision`
374
+ ever calls it — planning stays offline by construction (the keypoints file is
375
+ read like any other manifest input, never a network call), and the only
376
+ PixelLab endpoint `animate-skeleton`'s submission composes is
377
+ `animate-with-skeleton-v3` itself, not two never-tested-live calls chained
378
+ together. A future pipeline stage that budgets and tracks `estimate-skeleton`
379
+ calls the way `gen` does everything else is tracked separately, once this
380
+ mode has shipped and seen real use.
381
+
382
+ Cost uses PixelLab's own documented anchors (3 frames = 2 generations, 8 = 3,
383
+ 15 = 4 — barely moving with length, unlike `animate`/`animate-pixminimax`'s
384
+ canvas-area formula) and interpolates between the nearest two for any
385
+ in-between frame count, ceiling'd — the safe direction for `--budget` — since
386
+ no in-between value is confirmed live. **Neither `animate-with-skeleton-v3`
387
+ nor `estimate-skeleton` has been exercised against a live account**; request
388
+ field names come from the live `animate_with_skeleton_v3` MCP tool schema
389
+ (the same authoritative source already trusted for the character/object
390
+ family), not an observed call.
391
+
392
+ ComfyUI does not support this mode either, for the same structural reason as
393
+ `animate`/`animate-pixminimax`.
394
+
319
395
  ## Dependency gate
320
396
 
321
397
  `pixelkiln plan` reports a revision as `blocked` when its parent is not safe to
@@ -399,6 +475,19 @@ approval gate before shipping. See the
399
475
 
400
476
  ## PixelLab
401
477
 
478
+ `"engine": "pro-flash"` on an `image-to-image` or `inpaint` revision sends it to
479
+ PixelLab's Pro Flash tier instead: `/edit-image-pro-flash` (a text edit at the
480
+ source's own size; the canvas never grows) or `/inpaint-image-pro-flash`
481
+ (replaces only the mask's white pixels and keeps the rest exactly). It is the
482
+ same model the `imageProFlash` generator and the `pro-flash` character engine
483
+ use, priced on the same provisional Pro Flash tier (5 generations up to 96px,
484
+ 6 up to 208px, 9 beyond) instead of the 20–40 of the default Pro endpoints.
485
+ Sources must be 32 to 256px per side in multiples of 4; `strength` is refused,
486
+ since neither endpoint has one. The finished job is read the same way as the
487
+ default endpoints'. PixelLab also offers reference-image edits, a
488
+ `context_image` around an inpaint, and inpaint output layers; none is modeled
489
+ yet.
490
+
402
491
  PixelLab needs no bindings: `image-to-image` calls `/edit-images-v2`,
403
492
  `inpaint` calls `/inpaint-v3`, both as a plain background job polled the same
404
493
  way as every other PixelLab submission. `reduce-colors` calls `/reduce-colors`
@@ -451,6 +540,14 @@ further — there is nothing to ask.
451
540
  request/response shapes come from PixelLab's live OpenAPI document, not an
452
541
  observed call. Treat the exact field names as provisional until a real
453
542
  call confirms them.
543
+ - `animate-skeleton` calls `/animate-with-skeleton-v3`, also a real async
544
+ background job, at most 256 pixels per side and 3-15 frames (the frame
545
+ count comes from `keypointsFile`, not a manifest field). See
546
+ [Skeleton-driven animation](#skeleton-driven-animation) above for the full
547
+ field list, the `keypointsFile` shape, and the `estimateSkeleton`
548
+ CLI-only-and-never-in-the-submission-path decision. Same unverified-live
549
+ caveat as `animate`/`animate-pixminimax`, sourced from the live
550
+ `animate_with_skeleton_v3` MCP tool schema rather than an observed call.
454
551
 
455
552
  - The mask convention is fixed, not graph-defined like ComfyUI's: white marks
456
553
  the area to generate, black the area to preserve. There is no way to flip it.
@@ -522,16 +619,20 @@ hash, strength, and — for `reduce-colors` — `numColors`, the palette image's
522
619
  hash, and the dithering settings, or — for `animate`/`animate-pixminimax` —
523
620
  `frames`, `fps`, the last frame's hash, `direction`, and `enhancePrompt`
524
621
  (`interpolate` records `fps` and the end keyframe's hash; `edit-animation`
525
- records `fps`). For a set parent, the parent hash is one hash over every
526
- member's hash in order.
622
+ records `fps`), or — for `animate-skeleton` — the keypoints file's hash,
623
+ `skeletonTemplate`, and `description` (`direction` is recorded the same way;
624
+ `frames` comes from the keypoints file itself, same field, same staleness
625
+ rule as the others). For a set parent, the parent hash is one hash over
626
+ every member's hash in order.
527
627
  ComfyUI provider metadata also retains the same lineage beside the workflow
528
628
  hash.
529
629
 
530
630
  Changing the prompt, workflow, mode, strength, parent bytes, mask bytes, color
531
631
  count, palette image bytes, dithering settings, frame count, last frame
532
- bytes, direction, or enhancePrompt makes the child stale. Moving an unchanged
533
- parent, mask, palette image, or last frame file does not. When a child
534
- has a quality profile, the new raw output hash also invalidates its old quality
632
+ bytes, direction, enhancePrompt, keypoints file bytes, skeletonTemplate, or
633
+ description makes the child stale. Moving an unchanged parent, mask, palette
634
+ image, last frame file, or keypoints file does not. When a child has a
635
+ quality profile, the new raw output hash also invalidates its old quality
535
636
  record, so a revised image cannot inherit approval from an earlier generation.
536
637
 
537
638
  Commit the parent art or parent lock entry, masks, child output, child lock
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelkiln",
3
- "version": "0.65.0",
3
+ "version": "0.67.0",
4
4
  "description": "Manifest-driven pixel-art generation, review, recovery, and packaging with deterministic provenance.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -46,7 +46,8 @@
46
46
  "isometricTile",
47
47
  "objectPro",
48
48
  "uiAsset",
49
- "uiElement"
49
+ "uiElement",
50
+ "imageProFlash"
50
51
  ],
51
52
  "default": "map"
52
53
  },
@@ -503,7 +504,8 @@
503
504
  "isometricTile",
504
505
  "objectPro",
505
506
  "uiAsset",
506
- "uiElement"
507
+ "uiElement",
508
+ "imageProFlash"
507
509
  ],
508
510
  "default": "map"
509
511
  },
@@ -1010,6 +1012,7 @@
1010
1012
  "correct-pixelart",
1011
1013
  "animate",
1012
1014
  "animate-pixminimax",
1015
+ "animate-skeleton",
1013
1016
  "interpolate",
1014
1017
  "edit-animation"
1015
1018
  ]
@@ -1079,6 +1082,24 @@
1079
1082
  },
1080
1083
  "enhancePrompt": {
1081
1084
  "type": "boolean"
1085
+ },
1086
+ "keypointsFile": {
1087
+ "type": "string",
1088
+ "minLength": 1
1089
+ },
1090
+ "skeletonTemplate": {
1091
+ "type": "string",
1092
+ "minLength": 1
1093
+ },
1094
+ "description": {
1095
+ "type": "string",
1096
+ "minLength": 1
1097
+ },
1098
+ "engine": {
1099
+ "type": "string",
1100
+ "enum": [
1101
+ "pro-flash"
1102
+ ]
1082
1103
  }
1083
1104
  },
1084
1105
  "required": [
@@ -121,7 +121,8 @@
121
121
  "isometricTile",
122
122
  "objectPro",
123
123
  "uiAsset",
124
- "uiElement"
124
+ "uiElement",
125
+ "imageProFlash"
125
126
  ],
126
127
  "default": "map"
127
128
  },
@@ -246,6 +246,28 @@ which tutorial(s) demonstrated real (not hypothetical) demand for it.
246
246
  actually describe `uiAsset`'s pricing. Left unpatched from one data point:
247
247
  over-reading stays the safe `--budget` direction, but a real call likely
248
248
  costs about half of what `pixelkiln plan` prints, pending a second size.
249
+ - **Skeleton-driven animation** (`POST /animate-with-skeleton-v3`, beta,
250
+ tier 1+ subscription — pose a reference image frame-by-frame from a
251
+ supplied 18-joint skeleton per frame, instead of a text motion
252
+ description) — closed by the `revision` asset shape's `animate-skeleton`
253
+ mode; see `pixellab.md` and `docs/REVISIONS.md#skeleton-driven-animation`.
254
+ `POST /estimate-skeleton` (auto-derive a reference image's own keypoints)
255
+ is wrapped too, but deliberately kept outside the manifest pipeline — a
256
+ standalone `pixelkiln estimate-skeleton` CLI command, not a
257
+ `resolveSpecs`/`estimate()`-time call — so `animate-skeleton`'s submission
258
+ composes exactly one never-tested-live PixelLab endpoint, not two chained
259
+ together. **Correcting this catalog's own prior research**: this entry
260
+ used to also claim a distinct "animation to animation" endpoint existed,
261
+ for transferring an existing walk cycle's motion onto a different
262
+ character. Checked against the live `animate_with_skeleton_v3` MCP tool
263
+ schema: **there is no such endpoint.** The real composition is
264
+ `estimate-skeleton` run once per frame of a source animation, then
265
+ `animate-with-skeleton-v3` against a *different* reference image reusing
266
+ those keypoints — a two-endpoint composition a person can now build by
267
+ hand with the primitives above, not a primitive pixelkiln itself
268
+ automates. Neither `animate-with-skeleton-v3` nor `estimate-skeleton` has
269
+ been exercised against a live account; request field names come from the
270
+ MCP tool schema, not an observed call.
249
271
 
250
272
  - **Fonts** (`/generate-font-pro`, an 80-glyph atlas plus a `.ttf` from a
251
273
  style description) — no tutorial demonstrated it in depth, so demand is
@@ -326,12 +348,15 @@ quote/identity lookup — not billed):**
326
348
  exactly, reassuring cross-validation of the quote endpoint even though it
327
349
  is a quote, not a bill.
328
350
 
329
- Not modeled at all today: pixelkiln's `imagePro` generator and the `revision`
330
- asset shape's `image-to-image`/`inpaint` modes only ever call the non-Flash
331
- endpoints (`generate-image-v2`, `edit-images-v2`, `inpaint-v3`). Adding Pro
332
- Flash would mean a new generator (or a model/engine choice on the existing
333
- ones) plus a new inpaint `outputMethod` field and the `context_image`
334
- mechanism — real, scoped work, not a docs fix.
351
+ **Now modeled, in part:** the `imageProFlash` generator wraps `create`
352
+ (style image + `styleTraits`, 16–256px in multiples of 4), and a revision's
353
+ `"engine": "pro-flash"` sends `image-to-image` to `edit` (text method) and
354
+ `inpaint` to `inpaint`. A still's `source_image_id` is recorded and reused
355
+ when a Pro Flash character or object base's `reference` is that still's exact
356
+ file (issue #145). Still unmodeled: `edit`'s `"reference"` method, the
357
+ `use_color_palette_correction` flag, inpaint's `output_method` choice and the
358
+ `context_image` + `bounding_box` mechanism. Costs use the provisional quotes
359
+ above; none has been billed live yet.
335
360
 
336
361
  ## Map Workshop (scene composition)
337
362
 
@@ -364,22 +389,23 @@ native Godot 4 `TileSet` resource directly, verified in CI — worth knowing if
364
389
  Map Workshop parity is ever considered, since the export leg is arguably
365
390
  already solved better here than in PixelLab's own reference flow.
366
391
 
367
- ## Skeleton-driven animation and animation-to-animation motion transfer
368
-
369
- Two more animation mechanisms with no equivalent: **"Animate with skeleton"**
370
- (fit a rig template — bipedal, realistic, chibi, or quadruped body plans —
371
- generate two frames at a time with each accepted pair becoming context for
372
- the next, height/head-size/offset controls) and **"Animation to animation"**
373
- (transfer the motion/shape structure of an *existing* walk cycle onto a
374
- newly described or referenced character, frame budget capped by the source's
375
- canvas size). Both demonstrated in "How to Make Walking Animations for Pixel
376
- Art Characters in PixelLab." Neither exists in pixelkiln's `character`
377
- schema, which only knows named templates, v3 text loops, and pro loops — none
378
- take a user-supplied motion source or expose a skeleton-editing surface.
379
- Already flagged as explicitly out of scope in docs/PIXELLAB.md
380
- ("skeleton-driven animation"); animation-to-animation is new information not
381
- previously catalogued anywhere.
392
+ ## Animation-to-animation motion transfer
382
393
 
394
+ Transferring the motion of an *existing* walk cycle onto a newly described or
395
+ referenced character — demonstrated in "How to Make Walking Animations for
396
+ Pixel Art Characters in PixelLab." As corrected in the now-closed
397
+ skeleton-driven-animation entry above: this is not one endpoint, it is
398
+ `estimate-skeleton` run per frame of the source animation plus
399
+ `animate-with-skeleton-v3` against the new character's reference image
400
+ reusing those keypoints. Both primitives exist in this adapter now
401
+ (`animate-skeleton` revision mode, `pixelkiln estimate-skeleton`), so a
402
+ person can build this by hand today — chaining `estimate-skeleton` calls
403
+ across a source animation's frames into one keypoints file, then pointing an
404
+ `animate-skeleton` revision's `from` at a different character. What remains
405
+ a real gap is automating that chain as its own pixelkiln capability (one
406
+ command, not N manual `estimate-skeleton` calls plus hand-assembling the
407
+ result into a `SkeletonSetSchema` file) — worth scoping once the base
408
+ `animate-skeleton` mode has shipped and seen real use.
383
409
 
384
410
  ## Not PixelLab gaps at all — different products, no action implied
385
411
 
@@ -27,6 +27,7 @@ providers, or before any PixelLab account operation.
27
27
  | `character` | A character in 4 or 8 directions, its poses (`state`), and its loops (`animation`) | 1 per standard base, 6 per pro-flash base at 64px (1 from a `reference`), 20–40 per pose, 1 per template loop per direction |
28
28
  | `uiAsset` | A UI panel, button, health bar, or other chrome, from precise `pieces` and/or named `elements` | **20 generations, measured once** (256×192); the borrowed canvas-tier estimate still predicts 40 |
29
29
  | `uiElement` | One UI element (button, slot, bar, dialogue box) from the prompt, 16px and up, with an optional concept image | 20–40 generations, **unmeasured** |
30
+ | `imageProFlash` | A styled still on the Pro Flash model (style image + `styleTraits`), 16–256px in multiples of 4; also the natural source for a Pro Flash character's south sprite | 5–9 generations, PixelLab's provisional quote |
30
31
 
31
32
  `tiles` is not limited to top-down ground: `tileType` selects the projection
32
33
  (`isometric` — the API default —, `oblique`, `hex`, `hex_pointy`, `octagon`,
@@ -258,6 +259,15 @@ widgets under `uiAsset`'s 192px floor. Unmeasured: the plan borrows the
258
259
  20/25/40 canvas tiers, and the completed job's shape has not been observed
259
260
  live.
260
261
 
262
+ `imageProFlash` wraps `/create-image-pro-flash`, the Pro Flash model as a plain
263
+ still: priced 5 up to 96px, 6 up to 208px, 9 beyond (PixelLab's own
264
+ provisional `/pro-flash/cost` quotes). Its lock entry keeps PixelLab's
265
+ `source_image_id`; a Pro Flash character or object base whose `reference` is
266
+ byte-for-byte that still's file is sent the id instead of the upload (same
267
+ price, no re-encode). The same model edits and inpaints through a revision's
268
+ `"engine": "pro-flash"` (`image-to-image`/`inpaint` only, 32–256px in multiples
269
+ of 4, no `strength`), at the Pro Flash tier instead of the Pro endpoints' 20–40.
270
+
261
271
  Do not confuse pixelkiln's `map` generator with PixelLab's own "Map
262
272
  Workshop": `map` returns one static prop, icon, or building in a single
263
273
  generation with no scene, canvas, or placement concept. Map Workshop (scene
@@ -378,28 +388,43 @@ contained a generated signature-like glyph.
378
388
  An asset that declares `revision` against a PixelLab style calls `inpaint`
379
389
  (masked), `image-to-image` (whole-image, no mask), `reduce-colors`
380
390
  (palette quantize, `/reduce-colors`), `correct-pixelart` (edge/noise
381
- cleanup, `/correct-pixelart`), `animate` (`/animate-with-text-v3`), or
391
+ cleanup, `/correct-pixelart`), `animate` (`/animate-with-text-v3`),
382
392
  `animate-pixminimax` (`/animate-pixminimax`, beta, tier 1 subscription or
383
- higher), `interpolate` (`/interpolation-v2`, in-betweens from the parent to
384
- a required `lastFrame` keyframe), or `edit-animation` (`/edit-animation-v2`,
385
- one edit across a whole frame set); `outpaint` is refused, since PixelLab has no canvas-expansion
386
- endpoint. `reduce-colors`/`correct-pixelart` send no prompt to PixelLab at
387
- all — they are mechanical, not described — and complete synchronously with
388
- no background job, unlike every other PixelLab call this adapter makes.
389
- `animate`/`animate-pixminimax` DO send the asset's own prompt, as the motion
390
- description, and produce an ordered **frame set** landing in candidate
393
+ higher), `animate-skeleton` (`/animate-with-skeleton-v3`, also beta/tier
394
+ 1+ — poses the source frame-by-frame from a supplied 18-joint skeleton per
395
+ frame, via a committed `keypointsFile` rather than a text motion
396
+ description), `interpolate` (`/interpolation-v2`, in-betweens from the parent
397
+ to a required `lastFrame` keyframe), or `edit-animation` (`/edit-animation-v2`,
398
+ one edit across a whole frame set); `outpaint` is refused, since PixelLab has
399
+ no canvas-expansion endpoint. `reduce-colors`/`correct-pixelart` send no
400
+ prompt to PixelLab at all — they are mechanical, not described — and complete
401
+ synchronously with no background job, unlike every other PixelLab call this
402
+ adapter makes. `animate`/`animate-pixminimax`/`animate-skeleton` DO send the
403
+ asset's own prompt, as the motion description (`animate-skeleton` calls it
404
+ `action`, alongside a separate optional `description` field for appearance —
405
+ the skeleton carries the motion, the text only names it and what the subject
406
+ looks like), and produce an ordered **frame set** landing in candidate
391
407
  review, not a single image — the one revision mode shape that isn't "one
392
- image in, one image out." Neither animate endpoint's completed-job response
393
- shape has ever been observed; `pollAnimateRevision` guesses defensively
394
- rather than assume one. Read `docs/REVISIONS.md`'s PixelLab section before
395
- using any of these. A parent written as a set (a character's directions, an
396
- animation's frames) goes to `reduce-colors`, `correct-pixelart`, and
397
- `edit-animation` whole, in one call, so every member shares one palette or
398
- edit; the other modes refuse a set parent. `reduce-colors`/`correct-pixelart` cost is **confirmed
399
- live**: a flat 0.1 generations each (not the schema's dollar-denominated
400
- example), at least at a 32×32 source — `animate`/`animate-pixminimax` remain
401
- schema-only and unexercised, taken from PixelLab's live OpenAPI document
402
- rather than an observed call.
408
+ image in, one image out." None of the animate/interpolate/edit-animation
409
+ endpoints' completed-job response shape has ever been observed;
410
+ `pollAnimateRevision` guesses defensively rather than assume one. Read
411
+ `docs/REVISIONS.md`'s PixelLab section before using any of these. A parent
412
+ written as a set (a character's directions, an animation's frames) goes to
413
+ `reduce-colors`, `correct-pixelart`, and `edit-animation` whole, in one call,
414
+ so every member shares one palette or edit; the other modes refuse a set
415
+ parent. `reduce-colors`/`correct-pixelart` cost is **confirmed live**: a flat
416
+ 0.1 generations each (not the schema's dollar-denominated example), at least
417
+ at a 32×32 source — `animate`/`animate-pixminimax`/`animate-skeleton`/
418
+ `interpolate`/`edit-animation` remain schema-only and unexercised.
419
+ `animate-skeleton`'s request field names come from the live
420
+ `animate_with_skeleton_v3` MCP tool schema, a more authoritative source than
421
+ the OpenAPI document the others are taken from, but still not an observed
422
+ call. `estimate-skeleton` (auto-derive a reference image's own keypoints) is
423
+ wrapped too, but deliberately as a standalone `pixelkiln estimate-skeleton`
424
+ CLI command, never inside `submitRevision` — see
425
+ [pixellab-roadmap.md](./pixellab-roadmap.md)'s now-closed skeleton-driven-
426
+ animation entry for why composing two never-tested-live endpoints in one
427
+ submission was rejected.
403
428
 
404
429
  `animate-pixminimax`'s `direction` + `enhancePrompt` combination has a
405
430
  measured-in-practice gotcha, not just a schema quirk: PixelLab's own tutorial