Files
webstudio/packages/protocol
Oleg Isonen 0760d6cfec fix: upload videos from Builder and MCP (#6189)
## 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
2026-08-19 00:21:11 +02:00
..

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.