Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b6e9501
`@remotion/studio`: Preserve timeline markup order during Fast Refresh
JonnyBurger Aug 31, 2026
6e0c729
refactor(core): canonicalize playback state subscriptions
Octember Aug 31, 2026
61fdf74
Preserve committed order across Studio registrations
JonnyBurger Aug 31, 2026
4da87af
Remove obsolete ordering nonce system
JonnyBurger Aug 31, 2026
3dd2961
Skip empty Fiber commit order events
JonnyBurger Aug 31, 2026
61c86db
Merge pull request #11002 from remotion-dev/codex/fiber-sequence-time…
JonnyBurger Sep 1, 2026
4828940
`@remotion/media`: Upgrade Mediabunny to 1.55.5
JonnyBurger Sep 1, 2026
b0722bf
Docs: Add DTS as a public Mediabunny extension
JonnyBurger Sep 1, 2026
7d06b45
Merge pull request #11006 from remotion-dev/codex/upgrade-mediabunny-…
JonnyBurger Sep 1, 2026
b362e25
Merge pull request #10991 from Octember/codex/playback-state-transitions
JonnyBurger Sep 1, 2026
8c2528c
Prepare Agent Plugin releases for marketplaces
JonnyBurger Sep 1, 2026
38a754f
Add preview pitch shifting to @remotion/media
JonnyBurger Sep 1, 2026
7eb51b6
Merge pull request #11007 from remotion-dev/codex/prepare-agent-plugi…
JonnyBurger Sep 1, 2026
33a3e83
Document pitch shifting support matrix
JonnyBurger Sep 1, 2026
e6c933a
Rename Codex plugin package to Agent plugin
JonnyBurger Sep 1, 2026
c0d6594
Merge pull request #11009 from remotion-dev/codex/rename-codex-plugin…
JonnyBurger Sep 1, 2026
f3e1950
Distinguish pitch rendering environments
JonnyBurger Sep 1, 2026
841cfec
Attribute pitch shifting algorithm
JonnyBurger Sep 1, 2026
68c0a7d
Merge pull request #11008 from remotion-dev/codex/media-pitch-shifting
JonnyBurger Sep 1, 2026
bcca570
Fix maximum timeline zoom at 30 pixels per frame (#11010)
JonnyBurger Sep 1, 2026
a9843bd
Increase timeline waveform fidelity with composition FPS (#11011)
JonnyBurger Sep 1, 2026
accfdd3
Validate Agent Plugin builds with Vally
JonnyBurger Sep 1, 2026
ebb8cbd
Release waveform progress snapshot after loading
JonnyBurger Sep 1, 2026
d00dda4
Merge pull request #11014 from remotion-dev/codex/clear-waveform-prog…
JonnyBurger Sep 1, 2026
3111b92
Fix Kimi plugin skill expectations
JonnyBurger Sep 1, 2026
af71729
v4.0.520
JonnyBurger Sep 1, 2026
99b3ccc
Fix web renderer OPFS fallback and error details
JonnyBurger Sep 1, 2026
423af85
Fix Player resume timeout for manual playback
JonnyBurger Sep 1, 2026
12856a4
Preserve font weight value types in Inspector
JonnyBurger Sep 1, 2026
d45eb5a
Use larger steps for round font weights
JonnyBurger Sep 1, 2026
6587ffb
`@remotion/media`: Fix Windows decoder stalls
samohovets Sep 1, 2026
0a8d4ac
Reduce round font weight drag sensitivity
JonnyBurger Sep 1, 2026
63c36ef
Merge pull request #11016 from remotion-dev/codex/fix-player-autoplay…
JonnyBurger Sep 1, 2026
6171ee8
`@remotion/studio-codemods`: Split JSX without Prettier
JonnyBurger Sep 1, 2026
354341e
Merge pull request #11013 from remotion-dev/codex/validate-agent-plug…
JonnyBurger Sep 1, 2026
6cae96f
Use automatic output target for Studio web renders
JonnyBurger Sep 1, 2026
4d13f10
`@remotion/studio-codemods`: Remove JSX formatter compatibility APIs
JonnyBurger Sep 1, 2026
7c00c28
Merge pull request #11017 from remotion-dev/codex/font-weight-control
JonnyBurger Sep 1, 2026
f597ac0
Merge pull request #11018 from remotion-dev/fix-windows-decoder-outpu…
samohovets Sep 1, 2026
ed971ae
Merge pull request #11015 from remotion-dev/codex/fix-web-renderer-op…
JonnyBurger Sep 1, 2026
cfe1652
Merge pull request #11019 from remotion-dev/codex/manual-jsx-formatting
JonnyBurger Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1,146 changes: 516 additions & 630 deletions bun.lock

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,14 @@
"@types/node": "20.12.14",
"@types/web": "0.0.166",
"@types/bun": "1.3.3",
"mediabunny": "1.55.4",
"@mediabunny/server": "1.55.4",
"@mediabunny/mp3-encoder": "1.55.4",
"@mediabunny/aac-encoder": "1.55.4",
"@mediabunny/flac-encoder": "1.55.4",
"@mediabunny/prores": "1.55.4",
"@mediabunny/ac3": "1.55.4",
"@mediabunny/dts": "1.55.4",
"mediabunny": "1.55.5",
"@mediabunny/server": "1.55.5",
"@mediabunny/mp3-encoder": "1.55.5",
"@mediabunny/aac-encoder": "1.55.5",
"@mediabunny/flac-encoder": "1.55.5",
"@mediabunny/prores": "1.55.5",
"@mediabunny/ac3": "1.55.5",
"@mediabunny/dts": "1.55.5",
"next": "16.2.11",
"three": "0.178.0",
"sharp": "0.34.5",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "remotion",
"version": "4.0.519",
"version": "4.0.520",
"description": "Remotion video creation skills — best practices, animations, audio, captions, 3D, and more for building programmatic videos with React.",
"author": {
"name": "Remotion",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
28 changes: 28 additions & 0 deletions packages/agent-plugin/README.cursor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Remotion Agent Plugin

The official portable [Remotion](https://www.remotion.dev/) Agent Plugin. It
teaches compatible coding agents how to create videos with React, including
animations, audio, captions, 3D, transitions, charts, text effects, and
rendering.

## Install

Install Remotion from a compatible Agent Plugins marketplace. This portable
package is intended for clients such as GitHub Copilot and Cursor. For local
Cursor development, clone this repository:

```bash
git clone https://github.com/remotion-dev/cursor-plugin.git ~/.cursor/plugins/local/remotion
```

Restart Cursor after installing the local plugin.

## Development

This repository is generated from the
[`packages/agent-plugin`](https://github.com/remotion-dev/remotion/tree/main/packages/agent-plugin)
package in the Remotion monorepo. Changes made directly in this repository will
be overwritten by the release pipeline.

Please report issues and contribute changes in the
[`remotion-dev/remotion`](https://github.com/remotion-dev/remotion) repository.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# @remotion/codex-plugin
# @remotion/agent-plugin

## Usage

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@remotion/codex-plugin",
"version": "4.0.519",
"name": "@remotion/agent-plugin",
"version": "4.0.520",
"private": true,
"type": "module",
"repository": {
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/codex-plugin"
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/agent-plugin"
},
"scripts": {
"formatting": "oxfmt . --check",
Expand All @@ -19,13 +19,16 @@
"url": "https://github.com/remotion-dev/remotion/issues"
},
"devDependencies": {
"@microsoft/vally": "0.12.0",
"@remotion/eslint-config-internal": "workspace:*",
"eslint": "catalog:",
"@typescript/native-preview": "catalog:"
"@typescript/native-preview": "catalog:",
"eslint": "catalog:"
},
"keywords": [
"remotion",
"agent-plugin",
"codex",
"cursor",
"plugin",
"skills"
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "remotion",
"version": "4.0.519",
"version": "4.0.520",
"description": "Remotion video creation skills — best practices, animations, audio, captions, 3D, and more for building programmatic videos with React.",
"author": {
"name": "Remotion",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from 'node:fs';
import {tmpdir} from 'node:os';
import path from 'node:path';
import {LintConsoleReporter, runLint} from '@microsoft/vally';

const packageRoot = path.resolve(import.meta.dir, '..');
const generatedSkillsRoot = path.join(packageRoot, 'skills');
Expand Down Expand Up @@ -72,6 +73,23 @@ const getMarkdownFiles = (directory: string): string[] => {
});
};

const expectVallyLintToPass = async (
rootPath: string,
expectedSkillsRoot: string,
) => {
const result = await runLint({rootPath});
await new LintConsoleReporter({verbose: true}).report(result);

expect(result.skillResults.map(({skill}) => skill.name).sort()).toEqual(
getDirectories(expectedSkillsRoot),
);
expect(result.passed).toBe(true);
};

test('generated Agent Plugin passes Vally lint', async () => {
await expectVallyLintToPass(packageRoot, generatedSkillsRoot);
});

test('only top-level skills use the discovery filename', () => {
const topLevelSkillNames = getDirectories(generatedSkillsRoot);
for (const skillName of topLevelSkillNames) {
Expand Down Expand Up @@ -115,6 +133,30 @@ test('links to embedded skills use the renamed file', () => {
}
});

test('file links stay within each skill directory', () => {
for (const skillName of getDirectories(generatedSkillsRoot)) {
const skillRoot = path.join(generatedSkillsRoot, skillName);
for (const file of getMarkdownFiles(skillRoot)) {
const contents = readFileSync(file, 'utf-8');
for (const match of contents.matchAll(/!?\[[^\]]+]\(([^)]+)\)/g)) {
const target = match[1];
if (!target.startsWith('./') && !target.startsWith('../')) {
continue;
}

const targetWithoutFragment = target.split('#')[0];
const relativeTarget = path.relative(
skillRoot,
path.resolve(path.dirname(file), targetWithoutFragment),
);
expect(relativeTarget).not.toBe('..');
expect(relativeTarget.startsWith(`..${path.sep}`)).toBe(false);
expect(path.isAbsolute(relativeTarget)).toBe(false);
}
}
}
});

test('maps is available from either standalone parent skill', () => {
for (const parentSkill of ['remotion-best-practices', 'remotion-markup']) {
const parentRoot = path.join(generatedSkillsRoot, parentSkill);
Expand Down Expand Up @@ -156,7 +198,7 @@ test('Codex troubleshooting does not open the system browser', () => {
expect(remotionSkill).not.toMatch(/^npx remotion studio$/m);
});

test('Cursor build omits Codex troubleshooting', () => {
test('portable build passes Vally lint and omits Codex troubleshooting', async () => {
const cursorSkillsRoot = mkdtempSync(
path.join(tmpdir(), 'remotion-cursor-plugin-skills-'),
);
Expand Down Expand Up @@ -187,6 +229,7 @@ test('Cursor build omits Codex troubleshooting', () => {
);
expect(remotionSkill).not.toContain('## Codex troubleshooting');
expect(remotionSkill).not.toContain('## Agent client troubleshooting');
await expectVallyLintToPass(cursorSkillsRoot, cursorSkillsRoot);
} finally {
rmSync(cursorSkillsRoot, {recursive: true});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/animated-emoji/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remotion/animated-emoji",
"version": "4.0.519",
"version": "4.0.520",
"main": "dist/cjs/index.js",
"types": "dist/cjs/index.d.ts",
"module": "dist/esm/index.mjs",
Expand Down
2 changes: 1 addition & 1 deletion packages/animation-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"name": "Chetan Karwa",
"email": "cbkarwa@gmail.com"
},
"version": "4.0.519",
"version": "4.0.520",
"description": "Helpers for animating CSS properties",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
Expand Down
2 changes: 1 addition & 1 deletion packages/astro-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "@remotion/astro-example",
"private": true,
"type": "module",
"version": "4.0.519",
"version": "4.0.520",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/babel-loader"
},
"name": "@remotion/babel-loader",
"version": "4.0.519",
"version": "4.0.520",
"description": "Babel loader for Remotion",
"main": "dist/index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/brand/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/brand"
},
"name": "@remotion/brand",
"version": "4.0.519",
"version": "4.0.520",
"private": true,
"sideEffects": [
"*.css"
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-studio/e2e/browser-studio.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import {strFromU8, unzipSync} from 'fflate';

const localImagePath = fileURLToPath(
new URL('../../codex-plugin/assets/logo.png', import.meta.url),
new URL('../../agent-plugin/assets/logo.png', import.meta.url),
);
const localVideoPath = fileURLToPath(
new URL('../../example/public/framer.webm', import.meta.url),
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-studio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
},
"name": "@remotion/browser-studio",
"private": true,
"version": "4.0.519",
"version": "4.0.520",
"description": "Run Remotion Studio in the browser",
"main": "dist/esm/index.mjs",
"types": "dist/index.d.ts",
Expand Down
4 changes: 0 additions & 4 deletions packages/browser-studio/src/browser-studio-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@ const getElementInstallPlanForProject = async ({
compositionFile: destination.compositionFile,
compositionId: destination.compositionId,
environment: makeInMemoryInsertJsxElementCodemodEnvironment({
formatFile: formatCodemodFile,
project,
svgMarkupToJsx,
}),
Expand Down Expand Up @@ -1368,7 +1367,6 @@ export const createBrowserStudioOperations = ({
nodePath,
sequenceKeys,
splitFrame,
formatFile: formatCodemodFile,
});
const nodePathMutation = controller.applyMutation({
fileName: absolutePath,
Expand Down Expand Up @@ -1904,7 +1902,6 @@ export const createBrowserStudioOperations = ({
project: getProject(),
});
const result = await insertJsxElementIntoProjectWithNodePathRemappings({
formatFile: formatCodemodFile,
project,
request,
svgMarkupToJsx,
Expand Down Expand Up @@ -2048,7 +2045,6 @@ export const createBrowserStudioOperations = ({
const durationInFrames = request.element.durationInFrames ?? null;
const insertion =
await insertJsxElementIntoProjectWithNodePathRemappings({
formatFile: formatCodemodFile,
project,
request: {
compositionFile: request.compositionFile,
Expand Down
2 changes: 1 addition & 1 deletion packages/bugs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
},
"name": "bugs",
"private": true,
"version": "4.0.519"
"version": "4.0.520"
}
2 changes: 1 addition & 1 deletion packages/bundler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/bundler"
},
"name": "@remotion/bundler",
"version": "4.0.519",
"version": "4.0.520",
"description": "Bundle Remotion compositions using Webpack",
"main": "dist/index.js",
"bugs": {
Expand Down
2 changes: 1 addition & 1 deletion packages/canvas-capture-extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remotion/canvas-capture-extension",
"version": "4.0.519",
"version": "4.0.520",
"private": true,
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/canvas/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/canvas"
},
"name": "@remotion/canvas",
"version": "4.0.519",
"version": "4.0.520",
"description": "Headless primitives for Remotion authoring interfaces",
"main": "dist/index.cjs",
"types": "dist/index.d.ts",
Expand Down
15 changes: 9 additions & 6 deletions packages/canvas/src/calculate-timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type {
TimelineTrackWithOriginalTimings,
} from './get-timeline-sequence-sort-key';
import {getTimelineSequenceSortKey} from './get-timeline-sequence-sort-key';
import {sortItemsByNonceHistory} from './sort-by-nonce-history';
import {sortItemsByCommitOrder} from './sort-by-commit-order';
import {timelineSequenceNodePathToKey} from './timeline-sequence-node-path-to-key';

const getInheritedLoopDisplay = (
Expand Down Expand Up @@ -49,7 +49,10 @@ export const calculateTimeline = ({
overrideIdsToNodePaths: OverrideIdToNodePaths;
compositions?: readonly _InternalTypes['AnyComposition'][];
}): TimelineTrackData[] => {
const sortedSequences = sortItemsByNonceHistory(sequences);
const sortedSequences = sortItemsByCommitOrder(
sequences,
(sequence) => sequence.timelineOrder,
);
const tracks: TimelineTrackWithOriginalTimings[] = [];

if (sortedSequences.length === 0) {
Expand Down Expand Up @@ -142,15 +145,15 @@ export const calculateTimeline = ({
});
}

const nonceRanks = new Map<string, number>();
const sequenceRanks = new Map<string, number>();
for (let i = 0; i < tracks.length; i++) {
nonceRanks.set(tracks[i].sequence.id, i);
sequenceRanks.set(tracks[i].sequence.id, i);
}

const sortedTracks: TimelineTrackData[] = tracks
.sort((a, b) => {
const sortKeyA = getTimelineSequenceSortKey(a, tracks, nonceRanks);
const sortKeyB = getTimelineSequenceSortKey(b, tracks, nonceRanks);
const sortKeyA = getTimelineSequenceSortKey(a, tracks, sequenceRanks);
const sortKeyB = getTimelineSequenceSortKey(b, tracks, sequenceRanks);
return sortKeyA.localeCompare(sortKeyB);
})
.map((track) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/canvas/src/get-timeline-sequence-sort-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ export type TimelineTrackWithOriginalTimings = TimelineTrackData & {
export const getTimelineSequenceSortKey = (
track: TimelineTrackData,
tracks: TimelineTrackData[],
nonceRanks: Map<string, number>,
sequenceRanks: Map<string, number>,
): string => {
const rank = nonceRanks.get(track.sequence.id) ?? 0;
const rank = sequenceRanks.get(track.sequence.id) ?? 0;
const id = String(rank).padStart(6, '0');
if (!track.sequence.parent) {
return id;
Expand All @@ -45,5 +45,5 @@ export const getTimelineSequenceSortKey = (
return id;
}

return `${getTimelineSequenceSortKey(parent, tracks, nonceRanks)}-${id}`;
return `${getTimelineSequenceSortKey(parent, tracks, sequenceRanks)}-${id}`;
};
5 changes: 1 addition & 4 deletions packages/canvas/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,5 @@ export type {
CanvasSelectionInteraction,
CanvasSelectionSnapshot,
} from './selection';
export {
compareNonceHistories,
sortItemsByNonceHistory,
} from './sort-by-nonce-history';
export {sortItemsByCommitOrder} from './sort-by-commit-order';
export {timelineSequenceNodePathToKey} from './timeline-sequence-node-path-to-key';
Loading
Loading