@rig-c/core 2.41.0 → 2.42.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/README.md CHANGED
@@ -41,7 +41,7 @@ installed.
41
41
  | the same, and one texture instead of many | `rigc build --pack` | the parts arranged onto shared atlas pages, written beside the skeleton — losslessly, so the picture is the picture |
42
42
  | a pack somebody already made | `rigc build --atlas-in` | the same skeleton, with every part resolved to a region of that atlas — or a named refusal, never a part that silently does not draw |
43
43
  | a compiled rig | `rigc render` | every animation as PNG frames, plus one labelled contact sheet of the whole shot |
44
- | a compiled rig and a question about its geometry | `rigc inspect` | one picture of its bones, axes, a world grid or a declared axis over the art — at the setup pose, one time or a sheet of several, zoomed to a bone or a slot — and a legend that puts every mark back in world units |
44
+ | a compiled rig and a question about its geometry | `rigc inspect` | one picture of its bones, axes, mesh edges and hulls, one bone's weights, the draw order, a world grid or a declared axis over the art — at the setup pose, one time or a sheet of several, zoomed to a bone or a slot, or beside a second build on one transform — and a legend that puts every mark back in world units |
45
45
  | a compiled rig | `rigc preview` | one self-contained `.html` that plays it in Spine's own web player |
46
46
  | two to four compiled rigs | `rigc vote` | one ballot page a human picks from, and the answer checked into a ledger |
47
47
  | a picture of a key pose | `rigc pose` | where each loose part PNG sits in it, in spec coordinates — the movement between two poses is then yours to key ([docs/MOTION.md](docs/MOTION.md)) |
@@ -410,10 +410,14 @@ rigc inspect --candidate spine --show art,bones,names --dim # inspect.png + in
410
410
  bone where the art is*, *which way does it squash*, *where in rig units is this
411
411
  point*, *is this axis held*. It draws the build's art, framed as `render` frames it,
412
412
  and over it any of `bones` (origin to tip, a bone of length 0 marked as one),
413
- `names`, `axes` (each bone's world x and y), `grid` (in world units) and `declared`
413
+ `names` (one label per pixel), `axes` (each bone's world x and y), `mesh` and `hull`
414
+ (each mesh's edges and outline), `weights:<bone>` (what that bone moves, as a heat),
415
+ `slots` (the draw order at the pose), `grid` (in world units) and `declared`
414
416
  (each `invariants.axes` line and the bones held to it), at the setup pose, at
415
417
  `--animation <name> --at <s[,s…]>` — one picture, or a sheet — or zoomed with
416
- `--zoom <bone|slot>[:pad]` or `--viewport x,y,w,h`. Beside the PNG it writes a legend:
418
+ `--zoom <bone|slot>[:pad]` or `--viewport x,y,w,h`; `--bone`/`--hide-bone` pick the
419
+ bones by glob, and `--compare <dir>` draws a second build beside the first on one
420
+ transform, to see what a change moved. Beside the PNG it writes a legend:
417
421
  the world-to-pixel transform both ways, what each colour means, and every bone's
418
422
  origin and tip in world units and in pixels, so a position read off the picture goes
419
423
  straight back into the spec. [AUTHORING §13](docs/AUTHORING.md#13-asking-the-picture-a-question--rigc-inspect)
package/docs/AUTHORING.md CHANGED
@@ -10093,12 +10093,10 @@ pixel (`IN09`).
10093
10093
  | Where in rig units is this point? | `--show art,grid --zoom <bone or slot>` or `--viewport x,y,w,h` | grid lines at whole multiples of a step in **world units**, each labelled with its value, the lines through 0 darker. The legend's transform converts any pixel exactly; the grid is for reading by eye |
10094
10094
  | Is this axis declared, and held? | `--show art,declared,bones` | each `invariants.axes` line (§3.7) through its two bones' origins, drawn across the whole tile, and the bones it holds drawn in their own colour; the legend states each held bone's world x axis and how far off the line it lies, as `A51` measures it, at the pose drawn |
10095
10095
  | Did it break during the move? | any of the above `--animation <name> --at <s,s,…>` | one tile per time, left to right on one grid, each labelled with its time and frame |
10096
-
10097
- Two questions are not this cut's: **what does this bone move** (its weights over
10098
- the meshes it skins, the mesh edges and hulls, the slots' draw order) and **did this
10099
- change move anything** (two builds side by side on one grid). `--show mesh`,
10100
- `hull`, `weights:<bone>`, `slots` and `--compare` are refused as any unknown word
10101
- or flag is, naming what this version draws.
10096
+ | What does this bone move? | `--show art,mesh,weights:<bone> --dim` | the bone's weight over every region and mesh it moves, as a heat: a pixel whose centre lies in a triangle is painted the ramp's colour at the blend of its corners' weights — blue near 0, yellow at 0.5, red at 1 (the stops are in the legend) — and a weight of 0 is not painted, so the art shows where the bone does not reach. A region and an unweighted mesh are moved whole by their slot's bone. The weights are read off `skeleton.json`, the file both posers skin from; a bone that weights nothing paints nothing and the run says so on a line of its own |
10097
+ | How is this part triangulated? | `--show art,mesh,hull --zoom slot:<slot>` | each mesh's triangle edges, and over them its hull — vertex 0 to 1 to … to `hull − 1` and back. Regions are not drawn: a region is not a mesh. The legend lists every vertex in world units and in pixels |
10098
+ | Which is drawn over which? | `--show art,slots` | each slot that shows a region or mesh numbered by its place in the draw order **at the pose drawn** (0 is drawn first), on a white box at the centre of its attachment's box — so a `drawOrder` key (§4.7) shows from the first frame `render` draws it on |
10099
+ | Did this change move anything? | `--compare <dir>` beside any view | the same view of a second build beside the first, at the same times, on **one** world box and one transform, each half labelled `A`/`B` with the poser that posed it. A mark on a different pixel in the two halves is at a different place in the two rigs |
10102
10100
 
10103
10101
  ### 13.2 Where it looks
10104
10102
 
@@ -10119,11 +10117,40 @@ or flag is, naming what this version draws.
10119
10117
  (default a quarter of the box's longer side). A name that is both a bone and a slot
10120
10118
  is refused until it is written `bone:<name>` or `slot:<name>`; a bone of length 0
10121
10119
  with no pad is one point, and is refused asking for one.
10120
+ - **Two builds** — `--compare <dir | skeleton.json>`. The second build is loaded as
10121
+ the first is (its own poser, chosen by what it carries, on a `poser B:` line),
10122
+ posed at the same times, and drawn beside it: one time is two halves side by side,
10123
+ several are pairs, four to a row. The box is the one `--viewport` names, or the
10124
+ union of what `--zoom` names in **both** builds, or — with neither — the union of
10125
+ `render`'s framing of each, so a half is `render`'s frame of its build only where
10126
+ the two framings agree. A name either build lacks is refused naming that build.
10122
10127
  - `--max` is each tile's longer side in pixels (default 256), as on `render`.
10123
10128
  - `--dim` fades the art toward white (each channel keeps 0.4 of its distance from
10124
10129
  white) so what is drawn over it reads.
10125
10130
 
10126
- ### 13.3 The legend
10131
+ ### 13.3 Labels, and which bones are drawn
10132
+
10133
+ - **One label per pixel.** Bones whose origins land on one pixel — a `_ctl` bone and
10134
+ its identity child, a chain's joint — are one label: the first by declaration
10135
+ order, then `+N` for the rest (`leg0_ctl +2`). The pixel is the unit because it is
10136
+ what overprints: two origins a third of a pixel apart print their names on each
10137
+ other as surely as two that coincide. The legend's `labels` lists every bone of
10138
+ each label, and `bones` keeps every bone.
10139
+ - **No label over another.** Labels are placed in declaration order (slot numbers
10140
+ first); one that would touch an earlier label moves down a text line at a time
10141
+ until it is clear, and a grey leader joins it to its origin. After 16 lines it
10142
+ stays where it began and the legend marks it `overlaps`.
10143
+ - **`--bone <glob[,glob…]>`** draws only the bones a pattern matches, and
10144
+ **`--hide-bone <glob[,glob…]>`** none of the ones it matches, applied after
10145
+ `--bone` — so `--bone 'bang_*' --hide-bone '*_ctl,*_px'` is the fringe chains
10146
+ without their control bones. A pattern is a glob — `*` any run of characters, `?`
10147
+ one, matched against the whole name — rather than a regular expression: bone names
10148
+ are identifiers, the patterns are comma-separated, and a glob needs no escaping in
10149
+ the shell. The filter is on `bones`, `axes` and `names`; every bone stays in the
10150
+ legend, and a left-out one says which flag left it out in `undrawn`. A pattern
10151
+ that matches no bone is refused naming the bones there are.
10152
+
10153
+ ### 13.4 The legend
10127
10154
 
10128
10155
  `<out>.json` beside `<out>.png`, `rigc-inspect/1`. What it states:
10129
10156
 
@@ -10139,29 +10166,48 @@ or flag is, naming what this version draws.
10139
10166
  top-left pixel), and `bones[]` — every bone in declaration order with its
10140
10167
  `parent`, `length`, `zeroLength`, `origin` and `tip` each as `{ world, pixel }`,
10141
10168
  `undrawn` (why it is not drawn — its world matrix is 0 at this time, unposed by the
10142
- skin or scaled to 0 — or `null`), and with `axes` shown, the two axis ends. With
10143
- `grid`, the step and every line's value; with `declared`, each entry's line in
10144
- degrees, its two points, and each held bone's angle and how far off the line it is.
10169
+ skin or scaled to 0, or a `--bone`/`--hide-bone` pattern left it out — or `null`),
10170
+ and with `axes` shown, the two axis ends. With `grid`, the step and every line's
10171
+ value; with `declared`, each entry's line in degrees, its two points, and each held
10172
+ bone's angle and how far off the line it is. With `names`, `labels[]`: each label's
10173
+ `text`, the `bones` it stands for, its `anchor` pixel, the `box` it is drawn in,
10174
+ and whether it was `moved` or `overlaps`. With `mesh`, `hull` or `weights`,
10175
+ `meshes[]`: every region and mesh the pose shows, in draw order, with its `kind`,
10176
+ `vertexCount`, `triangleCount`, `hull` (a mesh's hull vertex count), its unique
10177
+ triangle `edges` as vertex pairs, every posed vertex in `world` and `pixel`, and
10178
+ with `weights` the bone's weight at each vertex. With `slots`, `slots[]`: each
10179
+ slot's `order`, `slot`, `attachment`, `bone`, its `anchor` and number's `box`.
10180
+ On a sheet or a compare, `label` — the tile's label text and box; with `--compare`,
10181
+ `build` — `A` or `B`.
10145
10182
  - `colours` — every colour the picture draws, as RGBA, with what it means.
10146
10183
  - `poser`, `show`, `dim`, `skin`, `animation`, `fps` and `framing` — what was drawn
10147
10184
  and how it was framed (`shot`, `zoom` with the bone or slot, the pad and whether it
10148
10185
  was stated, or `viewport`).
10186
+ - `weights` — with `weights:<bone>`: the bone, the ramp's stops as RGBA, the floor
10187
+ below which nothing is painted, and how a pixel's weight is read.
10188
+ - `boneFilter` — `--bone` and `--hide-bone` as given.
10189
+ - `builds` — with `--compare`: each build (`A`, `B`), the poser that posed it, and
10190
+ its `skeleton.json`'s sha256. `poser` is build `A`'s.
10149
10191
 
10150
10192
  Every number is `JSON.stringify`'s, the double the pose produced, not a rounding of
10151
10193
  it. The same build and flags write the same bytes (`IN10`).
10152
10194
 
10153
- ### 13.4 What it refuses
10195
+ ### 13.5 What it refuses
10154
10196
 
10155
10197
  Each of these exits 2, writes nothing, and names what exists: a bone or slot the
10156
10198
  build does not have (both rosters listed), an animation or skin it does not declare,
10157
10199
  a `--show` word it does not draw, a flag it does not take, a time off the frame grid
10158
10200
  or past the end, `--at` without `--animation` and the reverse, `--zoom` beside
10159
- `--viewport`, and `--show declared` on a skeleton with no `skeleton.model.json`
10160
- beside it whose `spine.sha256` is its own — a Spine export states no rig invariants.
10201
+ `--viewport`, `--show declared` on a skeleton with no `skeleton.model.json`
10202
+ beside it whose `spine.sha256` is its own — a Spine export states no rig invariants —
10203
+ `weights` with no bone or with a bone the build lacks (the bones listed), a
10204
+ `--bone`/`--hide-bone` pattern that matches no bone (the bones listed), and, with
10205
+ `--compare`, any of these that holds of the second build, said as `the --compare
10206
+ build: …`.
10161
10207
  A rig that declares no `invariants.axes` is not refused: the picture draws nothing
10162
10208
  for `declared` and the run says so on a line of its own.
10163
10209
 
10164
- ### 13.5 What it is not
10210
+ ### 13.6 What it is not
10165
10211
 
10166
10212
  - **Not a score.** Nothing in it is a pass bar; the picture is read, and what is read
10167
10213
  is acted on in the spec.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rig-c/core",
3
- "version": "2.41.0",
3
+ "version": "2.42.0",
4
4
  "description": "AI-authored 2D rigging and animation, verified before it is written. rigc compiles a rig spec into skeleton data in the Spine 4.3 format, gates it with named assertions held to a spine-core round trip's verdicts, and emits nothing that fails. Ships as an agent skill.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,7 +30,7 @@ import { ingest, INGEST_GUTTERS, type IngestFinding, IngestSpecRefused, type Ing
30
30
  import { PARSER_DEFAULTS, parserReading } from '../keyorder.ts';
31
31
  import { MODEL_DOCUMENT_FILE, modelDocument } from '../model.ts';
32
32
  import { parseMotionSpec } from '../motion.ts';
33
- import { type InspectFrame, InspectError, inspectCandidate, INSPECT_DEFAULT_FPS, legendText, readShowWords, readTimes, readZoom } from '../inspect.ts';
33
+ import { type InspectCompare, type InspectFrame, InspectError, inspectCandidate, INSPECT_DEFAULT_FPS, legendText, readBonePatterns, readShow, readTimes, readZoom } from '../inspect.ts';
34
34
  import { estimatePose, poseLines, type PoseOptions } from '../pose.ts';
35
35
  import { BACKGROUND, contactSheet, type Frame, FRAMES_SIDECAR, FRAMES_SPEC, type FrameSet, type FramesSidecar, framingViewport, GEOMETRY_FILE, geometryFileOf, geometryText, loadCandidate, POSER_NAMES, type PoserName, PROTOCOL_FPS, refuseUnchosen, renderFrame, sampleAll, sampleAnimation, SETUP_POSE_DIR, SHEET_FILE, SHEET_TILE, sidecarViewport, type SkeletonFacts, type SlotSubset, SlotSubsetError, throughPoser } from '../render_shared.ts';
36
36
  import { type CompileResult } from '../types.ts';
@@ -676,7 +676,10 @@ export function cmdInspect(flags: Record<string, string>): void {
676
676
  if (flags.zoom !== undefined && flags.viewport !== undefined) {
677
677
  throw new InspectError('--zoom and --viewport both choose the box the picture is of; give one of them');
678
678
  }
679
- const show = readShowWords(flags.show);
679
+ const { show, weightsBone } = readShow(flags.show);
680
+ const include = readBonePatterns('bone', flags.bone);
681
+ const exclude = readBonePatterns('hide-bone', flags['hide-bone']);
682
+ const boneFilter = include === undefined && exclude === undefined ? undefined : { ...(include === undefined ? {} : { include }), ...(exclude === undefined ? {} : { exclude }) };
680
683
  const times = readTimes(flags.at);
681
684
  const fps = readPositiveNumber(flags, 'fps', INSPECT_DEFAULT_FPS, 1);
682
685
  const maxSide = readPositiveNumber(flags, 'max', 256, 16);
@@ -709,14 +712,42 @@ export function cmdInspect(flags: Record<string, string>): void {
709
712
  const animation = readAnimationFlag(flags, [...candidate.facts.animations]) ?? null;
710
713
  readPoserFlag(flags);
711
714
  refuseUnchosen(candidate.choice);
715
+ // `--compare`: the second build, loaded the way the first was — its own poser chosen by what it carries, and said.
716
+ let compare: InspectCompare | undefined;
717
+ if (flags.compare !== undefined) {
718
+ const other = resolveDrawable(flags.compare, undefined);
719
+ const otherText = readSkeletonText(other.skeletonPath);
720
+ console.log(` .. compare ${other.skeletonPath}`);
721
+ const otherCandidate = loadCandidate(
722
+ { skeletonText: otherText, atlasText: other.atlasText, atlasDir: dirname(other.atlasPath), label: other.skeletonPath },
723
+ { skeleton: other.skeletonPath, atlas: other.atlasPath },
724
+ posersAsked(flags),
725
+ );
726
+ refuseUnchosen(otherCandidate.choice);
727
+ compare = { candidate: otherCandidate, texts: { skeletonText: otherText, modelText: modelTextBeside(other.skeletonPath, otherText) } };
728
+ }
712
729
  const result = inspectCandidate(
713
730
  candidate,
714
731
  { skeletonText, modelText: modelTextBeside(skeletonPath, skeletonText) },
715
- { show, dim: flags.dim !== undefined, animation, times, fps, skin: flags.skin, frame, maxSide },
732
+ {
733
+ show,
734
+ ...(weightsBone === undefined ? {} : { weightsBone }),
735
+ ...(boneFilter === undefined ? {} : { boneFilter }),
736
+ dim: flags.dim !== undefined,
737
+ animation,
738
+ times,
739
+ fps,
740
+ skin: flags.skin,
741
+ frame,
742
+ maxSide,
743
+ },
744
+ {},
745
+ compare,
716
746
  );
717
747
  const { legend } = result;
718
- console.log(` .. poser ${result.poserNote}`);
719
- const when = animation === null ? 'the setup pose' : `${animation} at ${legend.tiles.map((t) => `${t.time.toFixed(4)}s (frame ${t.frame})`).join(', ')}, ${fps} fps grid`;
748
+ console.log(` .. poser ${compare === undefined ? '' : 'A: '}${result.poserNote}`);
749
+ if (result.comparePoserNote !== undefined) console.log(` .. poser B: ${result.comparePoserNote}`);
750
+ const when = animation === null ? 'the setup pose' : `${animation} at ${legend.tiles.filter((t) => t.build !== 'B').map((t) => `${t.time.toFixed(4)}s (frame ${t.frame})`).join(', ')}, ${fps} fps grid`;
720
751
  console.log(` .. view ${legend.show.join(',')}${legend.dim ? ' over dimmed art' : ''} — ${when}`);
721
752
  const v = legend.viewport;
722
753
  // Four places for reading; the legend carries every number exactly.
package/src/cli/shared.ts CHANGED
@@ -56,7 +56,7 @@ import { BallotError } from '../ballot.ts';
56
56
  import { ChainFitError } from '../chainfit.ts';
57
57
  import { CheckError } from '../check.ts';
58
58
  import { IngestError, type IngestStage } from '../ingest.ts';
59
- import { InspectError, DEFAULT_SHOW, DIM_KEEP, INSPECT_DEFAULT_FPS, ON_GRID_FRAMES, SHOW_WORDS } from '../inspect.ts';
59
+ import { InspectError, DEFAULT_SHOW, DIM_KEEP, INSPECT_DEFAULT_FPS, ON_GRID_FRAMES, SHOW_SPELLINGS } from '../inspect.ts';
60
60
  import { NotAPngError } from '../png.ts';
61
61
  import { PoseError } from '../pose.ts';
62
62
  import { RepackError } from '../repack.ts';
@@ -1063,10 +1063,13 @@ const FLAG_MEANINGS: Record<string, string> = {
1063
1063
  'refused the same way. Not with `--slot`: the two are one statement',
1064
1064
  max: 'longest side of a rendered frame, in pixels (default 256)',
1065
1065
  show:
1066
- `what \`inspect\` draws, comma-separated, from [${SHOW_WORDS.join(', ')}] (default \`${DEFAULT_SHOW.join(',')}\`): art = the ` +
1067
- "build's own frame; grid = lines at whole multiples of a step in world units, labelled; declared = each invariants.axes " +
1066
+ `what \`inspect\` draws, comma-separated, from [${SHOW_SPELLINGS.join(', ')}] (default \`${DEFAULT_SHOW.join(',')}\`): art = the ` +
1067
+ "build's own frame; grid = lines at whole multiples of a step in world units, labelled; weights:<bone> = that bone's " +
1068
+ 'weight over every region and mesh it moves, as a heat on a ramp the legend states; mesh = each mesh\'s triangle edges; ' +
1069
+ "hull = each mesh's hull outline; declared = each invariants.axes " +
1068
1070
  "line through its two bones' origins, its held bones drawn in their own colour; bones = each bone from origin to tip, " +
1069
- 'a bone of length 0 marked as one; axes = each bone\'s world x and y axes; names = each bone\'s name. Any other word ' +
1071
+ 'a bone of length 0 marked as one; axes = each bone\'s world x and y axes; slots = each slot\'s place in the posed ' +
1072
+ 'draw order; names = the bones\' names, one label per pixel (bones sharing an origin pixel are "first +N"). Any other word ' +
1070
1073
  'is refused naming these',
1071
1074
  dim: `fade the art toward white (each channel keeps ${DIM_KEEP} of its distance from white), so what is drawn over it reads`,
1072
1075
  at:
@@ -1078,6 +1081,17 @@ const FLAG_MEANINGS: Record<string, string> = {
1078
1081
  'frame the picture to one bone (origin to tip) or one slot (its attachment\'s vertices) over every time drawn, padded ' +
1079
1082
  'by <pad> world units on every side (default: a quarter of the box\'s longer side). A name that is both a bone and a ' +
1080
1083
  'slot is refused until written bone:<name> or slot:<name>; a name that is neither lists both rosters. Not with --viewport',
1084
+ bone:
1085
+ "draw only the bones these globs match (`*` any run of characters, `?` one, the whole name; comma-separated) — on `inspect`, " +
1086
+ "for bones, axes and names; every bone stays in the legend, a left-out one saying why in `undrawn`. A pattern that matches no " +
1087
+ 'bone is refused naming the bones there are',
1088
+ 'hide-bone':
1089
+ "draw none of the bones these globs match — `--bone` the other way round, applied after it, so `--bone 'bang_*' " +
1090
+ "--hide-bone '*_ctl'` is the fringe chains without their control bones",
1091
+ compare:
1092
+ 'a second build to draw beside --candidate, the same view at the same times on one world box and one transform — the union ' +
1093
+ 'of both framings unless --zoom or --viewport pins it — each half labelled with its build and the poser that posed it. A ' +
1094
+ 'name, animation or skin the second build lacks is refused naming it',
1081
1095
  record: 'a saved vote to check against its ballot and append to the ledger, instead of writing a ballot',
1082
1096
  ballot: `the ballot the --record'd vote answers (default \`${DEFAULT_BALLOT}\`); its embedded manifest is what the vote is checked against`,
1083
1097
  ledger: `the append-only JSONL the vote lands in (default \`${DEFAULT_LEDGER}\`)`,
@@ -1178,6 +1192,9 @@ const FLAG_VALUES: Record<string, string> = {
1178
1192
  show: '<view[,view…]>',
1179
1193
  at: '<s[,s…]>',
1180
1194
  zoom: '<name>[:<pad>]',
1195
+ bone: '<glob[,glob…]>',
1196
+ 'hide-bone': '<glob[,glob…]>',
1197
+ compare: '<dir|skeleton.json>',
1181
1198
  record: '<result.json>',
1182
1199
  ballot: '<ballot.html>',
1183
1200
  ledger: '<votes.jsonl>',
@@ -1564,8 +1581,10 @@ export const COMMANDS: CommandDoc[] = [
1564
1581
  'rigc inspect --candidate <dir | skeleton.json> [--show art,bones,…] [--dim] [--max 256] [--poser core|spine] [--out inspect.png] (the setup pose)',
1565
1582
  'rigc inspect … --animation <name> --at <s[,s…]> [--fps 12] [--skin <name>] (one time, or a sheet of several on one grid)',
1566
1583
  'rigc inspect … --zoom <bone|slot>[:<pad>] | --viewport <x,y,w,h> (a box, in world units)',
1584
+ "rigc inspect … --bone 'bang_*' --hide-bone '*_ctl' (which bones bones, axes and names draw)",
1585
+ 'rigc inspect … --compare <dir | skeleton.json> (a second build beside the first, on one transform)',
1567
1586
  ],
1568
- flags: ['candidate', 'atlas', 'show', 'dim', 'animation', 'at', 'fps', 'skin', 'zoom', 'viewport', 'max', 'poser', 'out'],
1587
+ flags: ['candidate', 'atlas', 'show', 'dim', 'animation', 'at', 'fps', 'skin', 'zoom', 'viewport', 'bone', 'hide-bone', 'compare', 'max', 'poser', 'out'],
1569
1588
  overrides: {
1570
1589
  animation: { meaning: 'the animation --at reads its times from (default: the setup pose, with no --at)' },
1571
1590
  fps: { meaning: `the frame grid --at is read on, which is the grid \`render --fps\` draws (default ${INSPECT_DEFAULT_FPS})` },