@remotion/skills: Add remotion-export-otio skill - #10474
@remotion/skills: Add remotion-export-otio skill#10474krishnachitanyapidugu-sys wants to merge 3 commits into
@remotion/skills: Add remotion-export-otio skill#10474Conversation
Adds a public agent skill that exports a Remotion composition as an OpenTimelineIO (.otio) timeline for DaVinci Resolve or Premiere Pro. Media elements with a real src become clips, <Sequence from> determines placement, trimBefore becomes the source in-point, and everything without media behind it becomes a gap. Text, captions, effects and transitions are left out and reported to the user rather than mapped. Registers the skill in remotion-skill-names, the remotion-upgrade update command, the remotion-best-practices router and the docs page, and adds the symlinks and generated README from bun run syncskills. Related to remotion-dev#10235. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
97fb1f7 to
ba2e491
Compare
There was a problem hiding this comment.
Important
The new remotion-export-otio public skill is missing its agents/openai.yaml registration, which every other public skill ships. The @remotion/codex-plugin test skill display names match their slash commands reads agents/openai.yaml for every skill it packages, so the next build-and-test of the affected downstream packages will throw ENOENT on the missing file. The check list in the PR (checkskills + the four packages/cli tests) never exercises this path, which is why it slipped through.
Reviewed changes
- New public skill
remotion-export-otio—packages/skills/skills/remotion-export-otio/SKILL.md(230 lines) teaches an agent to translate a composition's<Video>/<Audio>/<OffthreadVideo>/optional<Img>into a track-per-kind OpenTimelineIO (.otio) timeline:RationalTime/TimeRangeidioms,Gap.1insertion for non-media spans,trimBefore→source_range.start_time, andavailable_rangefilled fromnpx remotion ffprobe. - Skill registration wiring — added
remotion-export-otioto the (sorted)remotionSkillNameslist inpackages/studio-server, thenpx skills update ... --yeslist inremotion-upgrade, a router section + symlink inremotion-best-practices, and a# /remotion-export-otioentry in the docsskills.mdxplus the generatedREADME.md. - Agent symlinks —
.agents/skills/remotion-export-otio → ../../packages/skills/skills/remotion-export-otio, surfaced through the.claude/skillsdirectory link; theremotion-best-practices/remotion-export-otiorouter symlink is present too.
⚠️ Missing agents/openai.yaml for the new public skill
Every public skill under packages/skills/skills/ ships an agents/openai.yaml — remotion-export-otio is the only one without it. @remotion/codex-plugin's test script (bun build.mts && SKILLS_ROOT=... validate-links.ts && bun test test) copies every skill directory into its packaged output, and the skill display names match their slash commands test then readFileSyncs agents/openai.yaml for each directory, so the build-and-test of the affected downstream packages fails with ENOENT once this skill is included. The author stated checks (checkskills and the four packages/cli skill tests) don't cover this packaging path, so it will surface only in the plugin tests.
Technical details
# Add agents/openai.yaml to remotion-export-otio
## Affected sites
- packages/skills/skills/remotion-export-otio/agents/openai.yaml — missing (only the SKILL.md is added in this PR)
- packages/codex-plugin/test/plugin.test.ts:195-203 — `readFileSync(generatedSkillsRoot/skillName/agents/openai.yaml)` for every packaged top-level skill; throws ENOENT without the file
## Required outcome
- Add packages/skills/skills/remotion-export-otio/agents/openai.yaml so the packaged skill exposes an OpenAI agent interface and the codex-plugin test passes.
- Verify with the codex-plugin (and cursor-plugin) build + test, which the current check list omits.
## Suggested approach
Mirror the other skills exactly (see packages/skills/skills/remotion-render/agents/openai.yaml):
interface:
display_name: '/remotion-export-otio'
short_description: 'Export a Remotion composition as an OpenTimelineIO (OTIO) timeline for DaVinci Resolve or Premiere Pro'
icon_small: './assets/remotion-icon.png'
icon_large: './assets/remotion-icon.png'
brand_color: '#0B84F3'
default_prompt: '$remotion-export-otio: Export this composition for DaVinci Resolve'
The openai.yaml references ./assets/remotion-icon.png, which every other public skill also carries under <skill>/assets/ — the new skill currently contains only SKILL.md, so copy that icon in alongside.DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
…-otio Every other public skill ships agents/openai.yaml and assets/remotion-icon.png. Without them the packaged skill has no OpenAI interface, and the codex-plugin test that reads agents/openai.yaml for every top-level skill fails with ENOENT. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Related to #10235.
That issue asks for a way to hand a Remotion edit over to DaVinci Resolve or Premiere. This PR proposes the smallest useful step in that direction: an agent skill that teaches an agent to produce a valid OpenTimelineIO (
.otio) file from a composition. No new package, no runtime code, no changes to shipped behaviour.I went with a skill rather than an exporter because a Remotion composition is React code, so there is no deterministic mapping from a component tree to a timeline. Deciding which elements are clips, where they sit, and what has to be dropped is a judgement call, which is the kind of thing a skill handles better than an API. If you would rather see this as a real exporter in a package, say so and I will close this and work on that instead.
What is in the PR
packages/skills/skills/remotion-export-otio/SKILL.md— the skillagents/openai.yamlandassets/remotion-icon.png, matching what every other public skill shipsremotion-skill-names.ts, thenpx skills updatelist inremotion-upgrade, a router entry inremotion-best-practices, and the docs page (packages/skills/README.mdis generated from it)bun run syncskillsWhat the skill does and does not claim
It maps
<Video>,<OffthreadVideo>and<Audio>with a realsrcinto OTIO clips, uses<Sequence from>for placement,trimBeforefor the source in-point, andGap.1for everything with no media behind it.It explicitly does not try to map text, captions, shapes, animations, effects or transitions. Those are React and have no media file, so no timeline format can carry them. The skill is written to leave them out and to tell the user exactly what it skipped, rather than pretend the export is lossless.
Testing
An exported timeline was imported into DaVinci Resolve and came in as expected.
The rest was validated against the reference implementation (OpenTimelineIO 0.18.1) rather than by eye:
otio_json, and converts to FCP7 XML for the Premiere pathotiostat: 2 tracks of equal length, 3 clips, 00:00:16:00, matchingdurationInFrames={480}at 30fpssource_rangefits inside the real file length as reported byffprobetrimBeforeis honouredtrimBefore, missing gap, missingavailable_range, captions emitted as clips) are each caught, so the passing result means somethingRepo checks:
bun run checkskillspasses, the four skill-related test files inpackages/clipass (5 tests), thecodex-plugin,claude-code-pluginandkimi-code-plugintest suites pass, and so dolintandformattingfor the affected packages.Two details the testing corrected in the skill text: the FCP XML adapter is no longer bundled with OpenTimelineIO and needs
otio-fcp-adapterplus-O fcp_xml, and that converter fails on any media reference without anavailable_range, so the skill tells the agent to fill it in fromnpx remotion ffprobe.