spine-rigc 0.14.1 → 0.16.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.
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "rigc",
3
+ "owner": {
4
+ "name": "firejune",
5
+ "url": "https://github.com/firejune"
6
+ },
7
+ "description": "rigc, the rig compiler for Spine, packaged as agent skills over the guides the npm package ships.",
8
+ "plugins": [
9
+ {
10
+ "name": "rigc",
11
+ "source": "./",
12
+ "description": "Author Spine 4.3 rigs with rigc: an entry skill with the install line and the build, validate, render, check and vote loop, plus routers for rigging, motion, faces and foreign skeletons, each linking the shipped guide that owns its rules.",
13
+ "homepage": "https://github.com/firejune/rigc#readme",
14
+ "repository": "https://github.com/firejune/rigc",
15
+ "license": "MIT",
16
+ "keywords": ["spine", "spine2d", "skeletal-animation", "rig", "compiler", "ai-agents"]
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
+ "name": "rigc",
4
+ "description": "Author Spine 4.3 rigs with rigc, the rig compiler that verifies its own output through a spine-core round-trip. Skills that route an agent to the shipped guide for the need at hand: the hierarchy, a motion, a face, or a skeleton somebody else authored.",
5
+ "author": {
6
+ "name": "firejune",
7
+ "url": "https://github.com/firejune"
8
+ },
9
+ "homepage": "https://github.com/firejune/rigc#readme",
10
+ "repository": "https://github.com/firejune/rigc",
11
+ "license": "MIT",
12
+ "keywords": ["spine", "spine2d", "skeletal-animation", "rig", "compiler", "ai-agents"]
13
+ }
package/LICENSE CHANGED
@@ -19,3 +19,12 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+
24
+ THIRD-PARTY MATERIAL
25
+
26
+ The licence above covers rigc's own code, documentation and art. It does not cover
27
+ third-party material distributed alongside them - in particular the rendered
28
+ reference frames under bench/reference/, which carry Esoteric Software's example
29
+ image data and are governed by each example's own license.txt beside them:
30
+ redistribution only with that file, and no commercial use. See NOTICE.md.
package/NOTICE.md CHANGED
@@ -54,9 +54,11 @@ Two consequences worth stating plainly:
54
54
  ## Example assets
55
55
 
56
56
  The official Spine example projects are the yardstick this compiler is measured
57
- against. They are owned by Esoteric Software and are **not redistributed** in this
58
- repository: `scripts/fetch-examples.sh` downloads them into a gitignored
59
- `examples/` directory for local evaluation.
57
+ against. They are owned by Esoteric Software. **The example projects themselves are
58
+ not committed to this repository**: `scripts/fetch-examples.sh` downloads them into a
59
+ gitignored `examples/` directory for local evaluation. What this repository *does*
60
+ commit is its own rendered frames of them, under the grant the examples' own licence
61
+ files carry — *Rendered reference frames*, below.
60
62
 
61
63
  Each example directory upstream carries its own `license.txt`, so the terms are
62
64
  per-directory rather than repository-wide. Verified on 2026-08-22 against
@@ -87,7 +89,9 @@ the copyright line:
87
89
  So, for this repository's purposes:
88
90
 
89
91
  - **Images** — redistributable only with the accompanying `license.txt`, and
90
- **non-commercial only**. That is why they are fetched rather than committed.
92
+ **non-commercial only**. That is why the example projects are fetched rather than
93
+ committed, and why the rendered frames this repository *does* commit each carry a
94
+ verbatim copy of that file beside them — *Rendered reference frames*, below.
91
95
  - **Project files** (`.spine`, and the exports derived from them) — **public
92
96
  domain**, usable as the basis for derivative work. This is what makes the
93
97
  examples usable as a structural yardstick.
@@ -95,3 +99,31 @@ So, for this repository's purposes:
95
99
  grant its siblings carry does not exist for it — there is no licence file to
96
100
  accompany its images with. `scripts/fetch-examples.sh` prints a warning naming
97
101
  it. Treat its images as not redistributable.
102
+
103
+ ### Rendered reference frames
104
+
105
+ `bench/reference/` contains **1,293 PNG frames rendered by this project** from the
106
+ examples' own exports: `bench/render_reference.ts` loads each example's `export/`
107
+ out of the gitignored `examples/`, poses it with `spine-core`, and rasterises each
108
+ posed attachment.
109
+
110
+ A rendered frame contains those images' pixels, so committing one **is**
111
+ redistribution — and each example's `license.txt` grants exactly that, *"as long as
112
+ they are accompanied by this license file"*. So **a verbatim copy of the relevant
113
+ `license.txt` sits at each example root** under `bench/reference/`, put there by
114
+ `render_reference.ts` rather than left to memory; all eight are present. The
115
+ **non-commercial** condition in that same file rides along with those images, and
116
+ `LICENSE` says so — rigc's MIT grant covers rigc's own code, documentation and art,
117
+ and does not extend to this material.
118
+
119
+ ⚠️ **`7-anticipation` is excluded, and mechanically so.** With no upstream
120
+ `license.txt` there is no grant to rely on, so its frames are never committed:
121
+ `render_reference.ts` writes them only into a gitignored directory, refuses any
122
+ `--out` inside the repository that `git check-ignore` will not accept, fails closed
123
+ if git cannot answer, and drops a `LOCAL-ONLY.txt` beside them in place of the
124
+ licence file that does not exist.
125
+
126
+ `bench/reference/` is repository material — it is not in `package.json`'s `files`
127
+ list, so it is not part of the published npm package. The full reasoning, and the
128
+ per-rung framing behind it, is in
129
+ [`bench/reference/README.md`](https://github.com/firejune/rigc/blob/main/bench/reference/README.md).
package/README.md CHANGED
@@ -18,7 +18,7 @@ their own work.
18
18
  <img src="https://raw.githubusercontent.com/firejune/rigc/main/assets/rigc-demo.gif" alt="Loose part PNGs assembling themselves into a character that breathes, blinks and waves" width="600" />
19
19
  </p>
20
20
 
21
- <p align="center"><em>Fourteen hand-drawn part PNGs, one rig spec, one motion spec — the assembly,
21
+ <p align="center"><em>Fourteen part PNGs drawn from scratch for this repo, one rig spec, one motion spec — the assembly,
22
22
  the breathing and the wave are all rigc-compiled Spine animations, rendered with
23
23
  <code>rigc render</code>.</em></p>
24
24
 
@@ -73,6 +73,22 @@ the following is a restatement of Esoteric Software's terms, not a term of ours:
73
73
 
74
74
  See [NOTICE.md](NOTICE.md) for the full notice.
75
75
 
76
+ 📐 **What of Esoteric Software's is in this repository, and under what grant.** No
77
+ example asset is committed: `bun run fetch-examples` downloads the example projects
78
+ into a gitignored `examples/`. What *is* committed is `bench/reference/` — 1,293 PNG
79
+ frames **this project renders** from those examples' own exports, so a frame carries
80
+ those images' pixels and committing one **is** redistribution. Each example's own
81
+ `license.txt` permits exactly that, *"as long as they are accompanied by this license
82
+ file"*, and a verbatim copy of it sits at each example root here — all eight, written
83
+ there by the render script rather than left to memory. The same file's
84
+ **non-commercial** condition rides along with those images, and
85
+ [LICENSE](LICENSE) says so: rigc's MIT grant covers rigc's own code, documentation
86
+ and art, not this material. `7-anticipation` publishes no `license.txt` upstream, so
87
+ no such grant exists for it and its frames are never committed — they render only
88
+ into a gitignored directory, enforced by `git check-ignore`. Full reasoning:
89
+ [`bench/reference/README.md`](https://github.com/firejune/rigc/blob/main/bench/reference/README.md)
90
+ (repository material, not in the npm package).
91
+
76
92
  The problem rigc is aimed at is narrow. An agent asked to author a rig has no way
77
93
  to tell whether it succeeded: Spine's JSON parser accepts a great deal of nonsense
78
94
  without a murmur — a constraint in the 4.2 shape simply vanishes, a `size:` that
@@ -114,10 +130,34 @@ the CLI in place); the two are interchangeable — `rigc build …` is
114
130
  `bun cli.ts build …`.
115
131
 
116
132
  Two commands are repository workflows rather than package ones: `bench` and
117
- `check` measure against Spine's official example projects and the reference
118
- frames rendered from them, which are fetched rather than redistributed (see
119
- [NOTICE.md](NOTICE.md)). They need a clone and `bun run fetch-examples`, and say
120
- so by name when the corpus is absent.
133
+ `check` measure against Spine's official example projects fetched, never
134
+ committed and against reference frames this project renders from them, which
135
+ **are** committed, each example's own `license.txt` beside them under the
136
+ redistribution grant those files carry; the images stay **non-commercial only**.
137
+ The reasoning is in
138
+ [`bench/reference/README.md`](https://github.com/firejune/rigc/blob/main/bench/reference/README.md)
139
+ and the terms in [NOTICE.md](NOTICE.md). Both commands need a clone and `bun run
140
+ fetch-examples`, and say so by name when the corpus is absent.
141
+
142
+ ### Install it into your agent
143
+
144
+ The guides under [Documentation](#documentation) also ship as
145
+ [Agent Skills](https://agentskills.io) — `skills/<name>/SKILL.md`, in this
146
+ repository and in the npm package — so an agent finds rigc the way it finds its
147
+ other tools. Each skill is a router and nothing more: when to load it, the
148
+ non-negotiables in a line apiece, and a link to the guide that owns every rule, so
149
+ a rule keeps living in exactly one place. The repository is also a Claude Code
150
+ plugin marketplace:
151
+
152
+ ```shell
153
+ /plugin marketplace add firejune/rigc
154
+ /plugin install rigc@rigc
155
+ ```
156
+
157
+ With the package already installed, `claude --plugin-dir node_modules/spine-rigc`
158
+ loads the same skills without a marketplace. The plugin carries no version of its
159
+ own — `/plugin update` follows `main` commit by commit, and the only version on
160
+ disk stays the one in `package.json`.
121
161
 
122
162
  ## First rig in ten minutes
123
163
 
@@ -386,7 +426,7 @@ limits: [AUTHORING.md §11](docs/AUTHORING.md). The parts it refuses because
386
426
  something is drawn over them are `rigc chainfit`'s, once a candidate exists —
387
427
  [§12](docs/AUTHORING.md).
388
428
 
389
- ## The gallery — five complete rigs over art that ships with them
429
+ ## The gallery — six complete rigs over art that ships with them
390
430
 
391
431
  Each directory in [`gallery/`](https://github.com/firejune/rigc/tree/main/gallery) is
392
432
  one rig spec, one motion spec and the PNGs they name, small enough to read in one
@@ -402,6 +442,7 @@ was verified, and what writing it cost. Repository material: a clone and
402
442
  | [`gallery/flex`](https://github.com/firejune/rigc/tree/main/gallery/flex) | **`contour` meshes** | A swallow-tailed banner and a serrated leaf: four meshes traced off their own alpha, waved by bone timelines and rippled by a `deform` |
403
443
  | [`gallery/ride`](https://github.com/firejune/rigc/tree/main/gallery/ride) | `path` attachments + **path constraints** | A trolley coasting down a drawn rail and rolling back, driven by a `position` timeline, with `groups` + `stagger` keying the wheels and the ears |
404
444
  | [`gallery/portrait`](https://github.com/firejune/rigc/tree/main/gallery/portrait) | **deform `transform`** + `derive` group tracks | A 2.5D head turn: two meshes and six feature bones all keyed from one stated expression, `dx = x(cos t − 1) − z·sin t`, with the depths in the spec rather than a README |
445
+ | [`gallery/nod`](https://github.com/firejune/rigc/tree/main/gallery/nod) | the **`pitch`** and **`wave`** transform kinds | A head bowing and two lop ears rippling, on three meshes each laid out for the closed form that moves it — a fold angle solved for before authoring, and a shear whose winding no amplitude can reverse |
405
446
 
406
447
  <p align="center">
407
448
  <img src="https://raw.githubusercontent.com/firejune/rigc/main/assets/rigc-scene.gif" alt="A portrait rig breathing, glancing aside, then turning its head in 2.5D — hair and features sliding at different depths" width="600" />
@@ -409,10 +450,17 @@ was verified, and what writing it cost. Repository material: a clone and
409
450
 
410
451
  <p align="center"><em>The portrait rig playing its three animations in one take — the turn is
411
452
  the shot: both silhouette edges move apart, which a flat slide cannot do, because every
412
- feature carries its own depth. Scene direction of this kind was Live2D's territory; the
413
- split was authoring cost, and the cost is now one stated expression per key. Compiled and
453
+ feature carries its own depth. Scene direction of this kind is authorable on plain Spine
454
+ 4.3 no plugin, no runtime patch and the split was authoring cost rather than runtime
455
+ capability; the cost is now one stated expression per key. Compiled and
414
456
  rendered entirely by the published package.</em></p>
415
457
 
458
+ 🎞️ **How the three films on this page were made** is kept with them, one directory per
459
+ film in [`films/`](https://github.com/firejune/rigc/tree/main/films) — a `run.sh` that
460
+ names every step, the assembler that cuts the shots and draws the type, and a README
461
+ saying what the film claims and which tool printed each figure on screen. Repository
462
+ material, like the gallery: a clone runs them.
463
+
416
464
  ## Commands
417
465
 
418
466
  Every command takes its paths explicitly. `rigc <command> --help` prints its flags, and
@@ -421,7 +469,7 @@ commands take it and what its default is.
421
469
 
422
470
  | Command | Does |
423
471
  | --- | --- |
424
- | `build --rig … --motion … --out …` | compiles, gates, and **writes only if the gate is green**. `--images <dir>` says where the rig spec's `image` names resolve, `--manifest` adds measured art, and `--copy-images` copies every page PNG into `--out` so the directory is self-contained |
472
+ | `build --rig … --motion … --out …` | compiles, gates, and **writes only if the gate is green**. `--images <dir>` says where the rig spec's `image` names resolve, `--manifest` adds measured art, and `--copy-images` copies every page PNG into `--out` so the directory is self-contained, with `skeleton.images` pointing at it so the editor's import finds the parts |
425
473
  | `build … --pack` | the same build with every part arranged onto **shared** atlas pages, written into `--out` — losslessly, and gated a second time as the pair that ships. `--page-size` and `--padding` tune it |
426
474
  | `build … --atlas-in <file.atlas>` | the same build with every part resolved to a **region of an existing pack** instead of a loose PNG; a name the atlas lacks, a size the spec disagrees with or a rectangle off its page is refused by name |
427
475
  | `validate <dir>` | re-gates artifacts already on disk |
@@ -442,7 +490,7 @@ and `bun run fetch-examples`. The reasoning behind all three is in
442
490
 
443
491
  `build` and `validate` both default to `--profile spine` — the 25 validity rules, which
444
492
  ask *is this valid Spine 4.3 that any runtime plays correctly?* `--profile spine-html`
445
- adds all 39: the other 14 are one renderer's policy and one canvas budget's, and they
493
+ adds all 40: the other 15 are one renderer's policy and one canvas budget's, and they
446
494
  fire on perfectly correct editor-produced Spine data, so reach for that profile when
447
495
  you are shipping into *that* project rather than to be thorough. A report always names
448
496
  the profile it ran and lists what that profile left out.
@@ -464,7 +512,7 @@ the art. Its shape is under
464
512
  | 📥 **[docs/INGEST.md](docs/INGEST.md)** | **working with a skeleton you did not author.** What every command can and cannot do with a foreign `skeleton.json`, reading it with the toolchain, transcription as the route that makes it yours, what each validator complaint means on an export, and the re-pivot/rename/extend recipes. Ships in the package too |
465
513
  | 🤖 **[docs/PROMPTING.md](docs/PROMPTING.md)** | **handing the authoring to an AI agent** — the prompt clauses a measured pilot run paid for, and what you can leave unsaid. Ships in the package too |
466
514
  | 🔬 **[docs/SPEC_COVERAGE.md](docs/SPEC_COVERAGE.md)** | Spine 4.3's full export surface against what rigc emits and what the official examples measurably use, with the ordered gap list |
467
- | 🎓 **[the benchmark dossier](https://github.com/firejune/rigc/blob/main/docs/BENCHMARK.md)** | **why you can trust the output.** The yardstick, `diff` and `check` and what neither can see, the eight-rung ladder and the spineboy graduation exam, the run viewer, the 36 named assertions with their profiles, and the selftest that has watched every one of them fire. Repository material — it is not in the npm package |
515
+ | 🎓 **[the benchmark dossier](https://github.com/firejune/rigc/blob/main/docs/BENCHMARK.md)** | **why you can trust the output.** The yardstick, `diff` and `check` and what neither can see, the eight-rung ladder and the spineboy graduation exam, the run viewer, the 40 named assertions with their profiles, and the selftest that has watched every one of them fire. Repository material — it is not in the npm package |
468
516
  | 📋 [LADDER.md](https://github.com/firejune/rigc/blob/main/docs/LADDER.md) · [GATE.md](https://github.com/firejune/rigc/blob/main/docs/GATE.md) · [PILOT.md](https://github.com/firejune/rigc/blob/main/docs/PILOT.md) | the live rung ledger, the clause statements a candidate is graded against, and how to run an agent through the ladder and score what comes back |
469
517
 
470
518
  ## Why you can trust the output
@@ -474,11 +522,12 @@ rigc is measured against **Spine's own official example projects** — the
474
522
  as the graduation exam.
475
523
 
476
524
  🎓 **The ladder is complete, 2026-08-28.** All eight numbered rungs and the
477
- spineboy graduation exam are cleared and hold under the current gate, **v2.3**, every clause PASS or SKIP:
478
- worst attributable slot drift **5.55 px** against a 6.0 px bar, and **0 of 124**
479
- frame-change disagreements. Recompiling the same spec in a different session
480
- reproduced every field of the measurement record **to the digit**. The rungs stay
481
- in place as regression gates.
525
+ spineboy graduation exam are cleared and hold under the current gate, **v2.4**, every clause PASS or SKIP:
526
+ worst attributable slot drift **5.5550 px** against a 6.0 px bar a **1.0801×**
527
+ margin, the thinnest of the ladder's **G2** figures, and **G5**'s 1.0376× is thinner
528
+ still and **0 of 124** frame-change disagreements. Recompiling the same spec in a
529
+ different session reproduced every field of the measurement record **to the digit**.
530
+ The rungs stay in place as regression gates.
482
531
 
483
532
  🗓️ **One rung's pass was withdrawn and restored on 2026-09-02, and both are dated
484
533
  facts.** `check`'s extent tolerance ([PR #254](https://github.com/firejune/rigc/pull/254))
@@ -489,11 +538,15 @@ clause questions that exposed, as **v2.3**: a read-down names the framing of its
489
538
  evidence, and a slot whose attributability is **measured** to be capped below the bar
490
539
  reads down when everything observable about it is independently verified strict. That
491
540
  rung's third attempt clears on those grounds, on the candidate it already had.
492
- **Rungs 1–6 and 8 and the graduation exam were unaffected throughout**: each reproduces
493
- its gated figures to the digit, and the 5.55 px and 0-of-124 figures above are among
494
- them. Both verdicts, and the sweep of every candidate under the new gate, are in
541
+ **Rungs 1–6 and 8 and the graduation exam were unaffected throughout**: each keeps its
542
+ pass on the clause, and recompiling a stored candidate reproduces its record **to the
543
+ digit within one gate**. Across an instrument change the digits do move, and the
544
+ record says where — the graduation **G2** figure went 5.5491 → 5.5544 → **5.5550 px**
545
+ over the #301 sampler repair and v2.4's adoption of the re-rendered reference basis,
546
+ while **0 of 124** held throughout. Both verdicts, and the sweep of every candidate under the gate of the day, are in
495
547
  [docs/LADDER.md](https://github.com/firejune/rigc/blob/main/docs/LADDER.md)'s *PR #254 instrument re-inspection* and *gate-v2.3
496
- re-inspection*.
548
+ re-inspection*; the standing figures quoted above are from its *gate-v2.4
549
+ re-inspection*, which is the current sweep.
497
550
 
498
551
  ⚠️ **What that certifies, stated exactly.** That **the tool, the guide and the
499
552
  protocol reach the bar across a bounded series of honest attempts, each residual
@@ -502,6 +555,17 @@ predecessor's specs under the run protocol's inheritance clause. It is **not**
502
555
  that an agent authors a spineboy-scale rig from the brief alone in one run: the
503
556
  ladder has not demonstrated that, and each row records which of the two it is.
504
557
 
558
+ 🧪 **A separate series measures that harder question, and it has not been kind.**
559
+ From-zero attempts at spineboy — no inherited specs — have landed at **18.2, 18.8,
560
+ 19.57, 7.86, 9.33 and 18.98 px** worst drift against the 6.0 px bar, a spread with no
561
+ monotone trend, and the two most recent — both **2026-09-03**, after the ladder's
562
+ 2026-08-28 completion — are recorded 🔴 **FAIL**. They move no rung and reopen nothing —
563
+ a from-zero run is a tooling-progress measurement rather than a re-climb, which is
564
+ why the certification above is scoped to tool + guide + protocol. One of those
565
+ attempts states the residual in its own words: *"in motion it is not at editor
566
+ quality."* All six, with their verdicts, are in
567
+ [docs/LADDER.md](https://github.com/firejune/rigc/blob/main/docs/LADDER.md).
568
+
505
569
  The whole dossier — the yardstick, `diff` and `check` and what neither of them can
506
570
  see, every rung, the run viewer, the 40 assertions and the selftest behind them — is
507
571
  [docs/BENCHMARK.md](https://github.com/firejune/rigc/blob/main/docs/BENCHMARK.md).
package/cli.ts CHANGED
@@ -727,9 +727,10 @@ function cmdBuild(flags: Record<string, string>): void {
727
727
  const { label, opts } = resolveCut(flags);
728
728
  const profile = readProfile(flags);
729
729
  const packing = flags.pack !== undefined;
730
- // Three combinations are refused rather than silently resolved, because in each
730
+ // Two combinations are refused rather than silently resolved, because in each
731
731
  // one the two flags disagree about a single question and there is no answer
732
- // that is not a guess about which the caller meant.
732
+ // that is not a guess about which the caller meant. (There were three until
733
+ // issue #266 — see the note below the second.)
733
734
  if (packing && opts.atlasInPath !== undefined) {
734
735
  throw new UsageError(
735
736
  '--pack and --atlas-in are opposite directions through the same door: --pack MAKES an atlas out of the ' +
@@ -742,13 +743,16 @@ function cmdBuild(flags: Record<string, string>): void {
742
743
  'the loose part PNGs, which a packed atlas does not reference. Drop --copy-images',
743
744
  );
744
745
  }
745
- if (packing && profile === 'spine-html') {
746
- throw new UsageError(
747
- "--profile spine-html asserts one part per page (A06's full-page coverage clause), which is rigc's unpacked " +
748
- 'convention and exactly what --pack stops being true. A packed atlas is valid Spine — build it under the ' +
749
- 'default --profile spine',
750
- );
751
- }
746
+ // The copy itself happens after the gate (below). The header has to know NOW,
747
+ // because the skeleton text the gate reads is the skeleton text that is written
748
+ // `skeleton.images` says where the parts will be (issue #370).
749
+ if (flags['copy-images'] !== undefined) opts.copyImages = true;
750
+ // `--pack --profile spine-html` used to be the third refusal here, because
751
+ // A06's coverage clause was "one part per page" flat and a legitimate pack
752
+ // arrived at the gate reading as a defect. Since issue #266's second follow-up
753
+ // that clause is "one part per page OR a tiling page", so the combination is
754
+ // now a build like any other — and it is the only one that puts the renderer's
755
+ // own rulebook over shared-page sampling.
752
756
  if (!packing) {
753
757
  for (const name of ['page-size', 'padding'] as const) {
754
758
  if (flags[name] !== undefined) throw new UsageError(`--${name} only means something with --pack`);
@@ -2248,12 +2252,13 @@ function cmdExplain(flags: Record<string, string>): void {
2248
2252
  const FLAG_MEANINGS: Record<string, string> = {
2249
2253
  rig: 'the rig spec — skeleton structure',
2250
2254
  motion: 'the motion spec — time',
2251
- out: 'directory for skeleton.json + skeleton.atlas; atlas page paths are written relative to it',
2255
+ out: 'directory for skeleton.json + skeleton.atlas; atlas page paths and skeleton.images are written relative to it',
2252
2256
  images: "override the rig spec's own images directory (relative to your working directory)",
2253
2257
  manifest: 'a cut manifest, for a rig with measured art behind it; a foreign skeleton has none',
2254
2258
  'copy-images':
2255
2259
  'also copy every referenced page PNG into --out and rewrite the atlas to the copies, so the directory is ' +
2256
- 'self-contained enough to zip or commit on its own (default: page paths still point at the source art)',
2260
+ 'self-contained enough to zip or commit on its own, and point skeleton.images at --out itself so the editor finds ' +
2261
+ 'the parts beside the skeleton on import (default: page paths still point at the source art)',
2257
2262
  pack: 'arrange every part PNG onto shared atlas page(s) written into --out as real PNGs, instead of one page ' +
2258
2263
  'per part. Lossless: every region is a byte-for-byte copy and nothing is resampled, trimmed or rotated ' +
2259
2264
  '(default: one part, one page, pointing at the source art)',