## Summary Video uploads failed because file detection returned `video` while the canonical Asset schema accepted only `font | image | file`. The mismatch was introduced when video detection was added in #5539; the recent JSON work only exposed the adjacent contract gap and did not cause it. This makes `video` a first-class `Asset["type"]` across Builder, SDK, storage formatting, project bundles, HTTP uploads, and MCP. There is no separate upload-only type and no conversion from `video` to `file`. ## Implementation - Add the canonical `video` Asset variant with width/height metadata. - Make Builder UI reservations and optimistic assets preserve `video`. - Make MCP and HTTP upload schemas derive their enum from the canonical SDK `assetType`. - Preserve video metadata through S3 and filesystem upload paths. - Include canonical video assets in project/canvas bundles. - Keep legacy video records without dimension metadata readable as generic `file` assets. - Fall back to a labeled file preview when the browser cannot decode a video format such as AVI; browser-supported formats continue to render video thumbnails. - Regenerate runtime operation contracts and sync fixtures from the PR deployment. ## Contract protection - Assert every detected upload category parses as a canonical Asset type. - Exercise Builder reservations for every value in `assetType.options`. - Assert MCP's upload enum exactly equals `assetType.options`. - Exercise direct HTTP video upload metadata and URL construction. - Cover canonical video formatting, legacy fallback, preview assets, and canvas serialization. - Verify a video decode error replaces the blank media element with a visible format-labeled fallback. - Store canonical WebM and MP4 records with dimensions in the `webstudio-features` fixture and verify generated runtime metadata. ## Checklist - [x] Make video a canonical Asset type - [x] Verify Builder UI upload flow - [x] Verify MCP and direct HTTP upload contracts - [x] Add fail/pass regression coverage for the broken paths - [x] Add an Assets panel fallback for browser-unsupported video formats - [x] Regenerate runtime contracts - [x] Sync and build fixtures against the PR deployment - [x] Run affected package tests, typechecks, lint, package-boundary, generated API, and generated docs checks - [x] Review documentation impact — existing Assets documentation already lists supported video formats and upload behavior; no user-facing documentation change is required ## Verification - Builder: 2,543 tests passed - Builder asset thumbnail regression: 14 tests passed - Project build/MCP runtime: 2,111 tests passed - CLI: 999 tests passed - SDK: 516 tests passed - Asset uploader: 199 tests passed - Protocol: 92 tests passed - HTTP client: 38 tests passed - Typechecks passed for Builder, SDK, asset uploader, project build, protocol, HTTP client, and CLI - Lint and package-boundary checks passed - Generated API and documentation checks passed - Fixture sync completed against `fix-video-up-be4d8a0.development.webstudio.is` - All fixture builds passed after synchronization Closes #6186
Protocol
@webstudio-is/protocol owns Webstudio data exchange protocols.
The project bundle is the external export/import artifact used by sync, local
.webstudio/data.json, project import, transferred asset files, and prebuild.
This package owns the assembled bundle schemas, transfer RPC payloads, and
bundle compatibility/version helpers.
Domain models such as pages, assets, and serialized builds remain owned by their domain packages and are composed here through schema-only entrypoints. Do not copy those schemas into this package.
Terminology
Project bundle is the authoritative external project artifact. It is used by
sync, .webstudio/data.json, project import, transferred asset files, and
prebuild.
Data envelope is a serialized single-key object whose key is a versioned
Webstudio marker, for example { "@webstudio/instance/v0.1": data }. The
envelope identifies the payload version and lets consumers detect malformed
Webstudio-owned data before falling back to other formats.
Transfer data is the domain payload inside a data envelope. Examples include
InstanceTransferData, InstancesTransferData, and PageTransferData.
Transfer data is portable and detached from a project; insertion/import remaps
ids and merges it into authoritative project state. Runtime-owned transfer
formats live in @webstudio-is/project-build/transfer.
Clipboard data is a UI transport concern. Builder copy/paste may serialize transfer data into a data envelope and place it on the browser clipboard, but runtime and protocol code should name the reusable format as data envelope or transfer data, not clipboard.