# Native Hyperframes authoring · phase one Read the pinned engine guide returned as `authoringGuide` by project details, or MCP resource `motion://engine/SKILL.md`. Relative engine Markdown references are available below `motion://engine/`. Skills are guidance; the host Agent writes the actual native video. ## Project loop 1. New work uses `motion_create_project` with a stable requestId, projectType, title and requirements. A prompt/reference creates a carrier, not a finished film. Template creation requires a real copyable builtin ID; select it through the Studio gallery or a provided guide. Existing work reuses its projectId. 2. `motion_get_project({projectId})` reads the explicit project, entry HTML, directory, file inventory, requirements, revision and current version. Without projectId it lists five projects per page; follow nextCursor. Never infer another chat's active project. 3. Read text through `motion_get_project({projectId,file:{path,offset,length},expectedRevision})`. Offsets are UTF-8 byte boundaries; follow nextOffset. Media bytes stay out of MCP text responses. 4. `motion_import_assets({projectId,requestId,items:[{itemId,sourcePath}]})` imports real local image/video/audio attachments in a batch. Each file must be at most 500 MB (500000000 bytes); compare exact bytes, not rounded MB. Source paths must exist on the server machine. Check every result and use the returned asset path. Import does not place media on the timeline. Keep stable itemIds for retries; never overwrite historical resources. Successful imports can create a new content version: reread project details before saving with expectedRevision/expectedVersionId. This Tool does not accept fonts, SVG/PDF, arbitrary binary files or remote URLs. Keep such files in an independent portable project using host capabilities; do not bypass managed-project guards by writing binary files directly. Inline SVG markup can be authored in native HTML. 5. `motion_edit_project({projectId,requestId,expectedRevision,expectedVersionId,files:[{path,content}]})` saves one batch of text files and optional requirements. Maximum 100 files / 8 MiB; metadata paths are reserved. All-or-none failure protection uses Studio's exclusive native history window and a recovery journal. Reread after a conflict; do not replay an old patch against unknown GUI changes. 6. For original creation, reference-video recreation and editable-template production, complete the editable preview handoff below once this turn's HTML output is ready. Existing-project content edits follow its continuing-edit rules before writing and after saving, regardless of the selected Skill. Other scopes open Studio on request. 7. Inspect actual motion, timing, sound and affected joins. Local/Studio changes become native content snapshots; querying flushes saved history metadata without editing source. Return to step 2 after GUI edits. ## Editable preview handoff The first output of original creation, reference-video recreation and editable-template production automatically includes an editable preview. Once the requested HTML and its supporting files/assets have been saved, call `motion_open_preview({projectId})` for that same project, then visibly open its exact returned `previewUrl` in the host's built-in browser. No additional user request or confirmation is needed. This includes drafts and unchanged template HTML; it does not wait for MP4 export. An empty carrier's `index.html` is not the requested output. Explicit user instructions to stay in the background take precedence. The Tool runs lint and selects an existing project in Studio; it does not create a project or open the host browser. Preserve the URL's embed/query/hash, verify that the intended project and current content loaded, and reuse its browser tab on continued work. If lint fails, fix the reported source problem before retrying. If preview or browser capability is unavailable, provide the project URL when available and state the concrete gap; report the page as opened only after observing it. Do not substitute the system `open` command, AppleScript or a separately launched visible browser for the host's browser. For an independent folder/ZIP, use a supported managed-project handoff if available; the public MCP has no general folder/ZIP adoption Tool. Preserve the actual source and report that limitation rather than opening an unrelated carrier. Preview preflight, export preflight and the OpenMotion command `node /scripts/lint-project.mjs ` use the native linter with `host: "studio"`. Structural errors therefore fail before the editor is opened or rendering begins; ordinary warnings remain non-blocking. A direct upstream `hyperframes lint` still uses its own CLI warning policy and is not proof that Studio will accept a project. ### Continuing edits Every content-editing turn saves the result and requests its preview in the same host chat. Reuse the project and native tab. Default `presentation:"foreground"` preserves the user's current chat: show the right panel when this chat is active; otherwise queue it until the user returns. Before writing, confirm project ownership and the current source/version; show the target when this chat is active. Apply this shared rule across production, director, template and recreation edits. After the final source batch, complete the applicable delivery branch: 1. Take `projectId`, `revision` and `versionId` from the save's `previewHandoff`. Call its `nextAction` (`motion_open_preview` with both expected identities) when the HTML is ready. A conflict means reread the current project and source, preserve intervening GUI changes, and prepare the preview with the newly read identities. Studio can add source handles on first open; do not overwrite that normalization with the old batch. Verify and acknowledge the current version returned by the successful open. 2. Request the same project's native preview on the right. In Codex, call `open_in_codex` with `placement:"right"` in the calling chat; omit `threadId` unless the user asked for another chat. The host queues the action when its target chat is inactive. Reuse the actual native Tab ID when available; CUA wrapper `id` is not the host's `providerTabId`. A hidden `browser-use:` tab may be separate from the native right-panel tab. Without an established native Tab ID use the exact returned `previewUrl`, preserving embed/query/hash. Reuse an already queued same-project live preview while subsequent edits update that project; avoid duplicate tabs or a queue of frozen versions. 3. Read the host acknowledgment **and separately observe visibility**. `queued` is neither success nor failure evidence. Rebind the actual native panel tab; a previous hidden automation tab can report false while a native tab is visible. In Codex IAB, after binding that tab, call the browser's supported `visibility.set(true)` capability once: it requests the calling chat's panel, queues while that chat is inactive, and does not navigate to it. Do not substitute another host's unverified focus-changing API. Observe `visibility.get()` as the host settles (bounded by the handoff's `settleTimeoutMs`); an immediate false can precede queued panel activation. If inactive, leave it queued and finish with “saved; latest preview will appear when you return.” Navigation remains forbidden by default. A still-hidden active-chat panel is a display failure to report. A closed/collapsed panel is not a request to skip preview entirely. 4. When the user returns, the host consumes its queued action. If executing a follow-up observation, use the handoff's `onReturn` action to resolve the **latest** project version, rather than replaying an old version-bound open or acknowledging the queued version. Locate the newest changed content at the affected time in the live preview, then recheck host visibility after inspecting it. A hidden WebContents screenshot, DOM `visibilityState`, metadata, a source read, file-watcher notification and a successful open alone do not prove visible freshness. Reload that native tab once if stale; preserve saved content and report any remaining failure. The host queue, not a continuing model turn, owns opening when the user returns; without a new observation leave the receipt pending. In disposable tests, consume queued actions before closing their tabs/server so an old queued tab cannot reappear later. 5. Record `motion_open_preview({action:"record_display",projectId,requestId,presentation,display:{revision,versionId,previewUrl,visibility,hostStatus,hostTabId,contentVerified,evidence}})` with the observed current version and a stable requestId per observation. Optional `hostStatus` preserves the acknowledgment (`queued` can coexist with actual `visibility:"visible"`); optional `hostTabId` preserves the established native ID as a reuse hint, validated against the current inventory. A closed tab's stale ID is omitted in favor of the fresh URL. A queued/hidden observation stays pending; only a visible preview with the latest content actually inspected can be `confirmed`. Deferred delivery is reported as queued, without claiming the user has seen it or polling indefinitely. Only an explicit request such as “show it now / 现在展示” permits `presentation:"now"` for this turn, carried through save/open/display calls. Its recovery may take the verified calling-chat `threadId` from `open_in_codex`, call `navigate_to_codex_page({threadId})` once, and present/recheck the native tab. Use the host chat identity, not the OpenMotion sessionId. This permission does not persist into later ordinary edits. An ordinary “finish editing” or hidden/queued state is not immediate-display authorization. This receipt is **host-reported evidence**, not an independent server measurement of the outer panel or user acceptance. The server rejects stale content versions, including a restored version with the same revision hash. `motion_get_project.previewDisplay` is a historical observation; `isCurrentVersion` says whether its content identity still matches, while `liveVisibilityVerified` remains false. Reobserve visibility each turn. An explicit user instruction to keep work in the background skips opening/focusing the editor. Carry that preference across turns until the user changes it; pass `presentation:"background"` on those saves. Default foreground saves return a pending handoff. Capability failures keep presentation pending; they do not undo the source save. A local implementation or source edit does not install/reload the host plugin. ## Native composition contract - Root: `data-composition-id`, `data-start="0"`, `data-duration`, `data-width`, `data-height`, and optional `data-fps`. - Scene hosts: unique `id`, matching `data-composition-id`, `data-composition-src="compositions/scene.html"`, `data-start`, `data-duration`, and `data-track-index`. Scene files wrap markup, styles and scripts inside `