The studio could only write runtime definitions: createAvatarDefinition is
one-way, and the sole file picker fed everything to parseImportedStudioDocument,
which rejects a definition for lacking version/library/expressions/sequences.
There was no way to bring an exported avatar back in.
Add the inverse mapping and wire it into the avatar library:
- studioAvatarFromDefinition() rebuilds a StudioAvatar, its expressions and its
sequences from a definition. `neutral` is deliberately not restored as an
expression: it is a reserved semantic key that lives on the avatar as eye
defaults and is re-emitted on export.
- The import picker now sniffs the format. A definition adds one avatar and
keeps the rest of the library; a studio project still replaces the document.
- Avatars tab: the "+" card opens a menu offering a new avatar or an import.
- Avatar editor: an Exporter button beside Dupliquer downloads the avatar as
.avatar.json, disabled with the validation error as a tooltip when the
definition would not validate.
- Menu primitive built on the existing @base-ui/react dependency, matching
context-menu.tsx. No new packages.
The round-trip test imports the repo's strobi.avatar.json fixture and exports it
again, asserting identical body, colors, expressions and ordering, so the two
directions cannot drift.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>