pixelkiln 0.66.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.
package/docs/MANIFEST.md CHANGED
@@ -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,14 @@ 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. |
484
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. |
485
488
 
486
489
  The parent may use committed `source`, downloaded generated output, or a
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
@@ -464,6 +540,14 @@ further — there is nothing to ask.
464
540
  request/response shapes come from PixelLab's live OpenAPI document, not an
465
541
  observed call. Treat the exact field names as provisional until a real
466
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.
467
551
 
468
552
  - The mask convention is fixed, not graph-defined like ComfyUI's: white marks
469
553
  the area to generate, black the area to preserve. There is no way to flip it.
@@ -535,16 +619,20 @@ hash, strength, and — for `reduce-colors` — `numColors`, the palette image's
535
619
  hash, and the dithering settings, or — for `animate`/`animate-pixminimax` —
536
620
  `frames`, `fps`, the last frame's hash, `direction`, and `enhancePrompt`
537
621
  (`interpolate` records `fps` and the end keyframe's hash; `edit-animation`
538
- records `fps`). For a set parent, the parent hash is one hash over every
539
- 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.
540
627
  ComfyUI provider metadata also retains the same lineage beside the workflow
541
628
  hash.
542
629
 
543
630
  Changing the prompt, workflow, mode, strength, parent bytes, mask bytes, color
544
631
  count, palette image bytes, dithering settings, frame count, last frame
545
- bytes, direction, or enhancePrompt makes the child stale. Moving an unchanged
546
- parent, mask, palette image, or last frame file does not. When a child
547
- 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
548
636
  record, so a revised image cannot inherit approval from an earlier generation.
549
637
 
550
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.66.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,
@@ -1012,6 +1012,7 @@
1012
1012
  "correct-pixelart",
1013
1013
  "animate",
1014
1014
  "animate-pixminimax",
1015
+ "animate-skeleton",
1015
1016
  "interpolate",
1016
1017
  "edit-animation"
1017
1018
  ]
@@ -1082,6 +1083,18 @@
1082
1083
  "enhancePrompt": {
1083
1084
  "type": "boolean"
1084
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
+ },
1085
1098
  "engine": {
1086
1099
  "type": "string",
1087
1100
  "enum": [
@@ -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
@@ -367,22 +389,23 @@ native Godot 4 `TileSet` resource directly, verified in CI — worth knowing if
367
389
  Map Workshop parity is ever considered, since the export leg is arguably
368
390
  already solved better here than in PixelLab's own reference flow.
369
391
 
370
- ## Skeleton-driven animation and animation-to-animation motion transfer
371
-
372
- Two more animation mechanisms with no equivalent: **"Animate with skeleton"**
373
- (fit a rig template — bipedal, realistic, chibi, or quadruped body plans —
374
- generate two frames at a time with each accepted pair becoming context for
375
- the next, height/head-size/offset controls) and **"Animation to animation"**
376
- (transfer the motion/shape structure of an *existing* walk cycle onto a
377
- newly described or referenced character, frame budget capped by the source's
378
- canvas size). Both demonstrated in "How to Make Walking Animations for Pixel
379
- Art Characters in PixelLab." Neither exists in pixelkiln's `character`
380
- schema, which only knows named templates, v3 text loops, and pro loops — none
381
- take a user-supplied motion source or expose a skeleton-editing surface.
382
- Already flagged as explicitly out of scope in docs/PIXELLAB.md
383
- ("skeleton-driven animation"); animation-to-animation is new information not
384
- previously catalogued anywhere.
392
+ ## Animation-to-animation motion transfer
385
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.
386
409
 
387
410
  ## Not PixelLab gaps at all — different products, no action implied
388
411
 
@@ -388,28 +388,43 @@ contained a generated signature-like glyph.
388
388
  An asset that declares `revision` against a PixelLab style calls `inpaint`
389
389
  (masked), `image-to-image` (whole-image, no mask), `reduce-colors`
390
390
  (palette quantize, `/reduce-colors`), `correct-pixelart` (edge/noise
391
- cleanup, `/correct-pixelart`), `animate` (`/animate-with-text-v3`), or
391
+ cleanup, `/correct-pixelart`), `animate` (`/animate-with-text-v3`),
392
392
  `animate-pixminimax` (`/animate-pixminimax`, beta, tier 1 subscription or
393
- higher), `interpolate` (`/interpolation-v2`, in-betweens from the parent to
394
- a required `lastFrame` keyframe), or `edit-animation` (`/edit-animation-v2`,
395
- one edit across a whole frame set); `outpaint` is refused, since PixelLab has no canvas-expansion
396
- endpoint. `reduce-colors`/`correct-pixelart` send no prompt to PixelLab at
397
- all — they are mechanical, not described — and complete synchronously with
398
- no background job, unlike every other PixelLab call this adapter makes.
399
- `animate`/`animate-pixminimax` DO send the asset's own prompt, as the motion
400
- 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
401
407
  review, not a single image — the one revision mode shape that isn't "one
402
- image in, one image out." Neither animate endpoint's completed-job response
403
- shape has ever been observed; `pollAnimateRevision` guesses defensively
404
- rather than assume one. Read `docs/REVISIONS.md`'s PixelLab section before
405
- using any of these. A parent written as a set (a character's directions, an
406
- animation's frames) goes to `reduce-colors`, `correct-pixelart`, and
407
- `edit-animation` whole, in one call, so every member shares one palette or
408
- edit; the other modes refuse a set parent. `reduce-colors`/`correct-pixelart` cost is **confirmed
409
- live**: a flat 0.1 generations each (not the schema's dollar-denominated
410
- example), at least at a 32×32 source — `animate`/`animate-pixminimax` remain
411
- schema-only and unexercised, taken from PixelLab's live OpenAPI document
412
- 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.
413
428
 
414
429
  `animate-pixminimax`'s `direction` + `enhancePrompt` combination has a
415
430
  measured-in-practice gotcha, not just a schema quirk: PixelLab's own tutorial