@remotion/cli 4.0.505 → 4.0.506

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import type { BundlerOverrideFn, RspackConfiguration, RspackOverrideFn, WebpackConfiguration, WebpackOverrideFn } from '@remotion/bundler';
2
- import type { BrowserExecutable, ChromeMode, CodecOrUndefined, ColorSpace, Crf, DeleteAfter, DefaultEditor, FrameRange, NumberOfGifLoops, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
2
+ import type { BrowserExecutable, ChromeMode, CodecOrUndefined, ColorSpace, Crf, DefaultCodingAgent, DefaultEditor, DeleteAfter, FrameRange, NumberOfGifLoops, StillImageFormat, VideoImageFormat } from '@remotion/renderer';
3
3
  import type { HardwareAccelerationOption } from '@remotion/renderer/client';
4
4
  import type { Concurrency } from './concurrency';
5
5
  export type { BundlerOverrideFn, Concurrency, RspackConfiguration, RspackOverrideFn, WebpackConfiguration, WebpackOverrideFn, };
@@ -388,6 +388,10 @@ type FlatConfig = RemotionConfigObject & RemotionBundlingOptions & {
388
388
  * Set the editor used when opening files from Remotion Studio.
389
389
  */
390
390
  setDefaultEditor: (editor: DefaultEditor) => void;
391
+ /**
392
+ * Set the coding agent used by Remotion Studio.
393
+ */
394
+ setDefaultCodingAgent: (codingAgent: DefaultCodingAgent) => void;
391
395
  setDeleteAfter: (day: DeleteAfter | null) => void;
392
396
  /**
393
397
  * Set whether S3 buckets should be allowed to expire.
@@ -18,7 +18,7 @@ const preview_server_1 = require("./preview-server");
18
18
  const still_frame_1 = require("./still-frame");
19
19
  const webpack_caching_1 = require("./webpack-caching");
20
20
  const webpack_poll_1 = require("./webpack-poll");
21
- const { benchmarkConcurrenciesOption, concurrencyOption, offthreadVideoCacheSizeInBytesOption, x264Option, audioBitrateOption, videoBitrateOption, scaleOption, crfOption, jpegQualityOption, enforceAudioOption, overwriteOption, chromeModeOption, mutedOption, videoCodecOption, colorSpaceOption, disallowParallelEncodingOption, deleteAfterOption, folderExpiryOption, enableMultiprocessOnLinuxOption, glOption, gopSizeOption, headlessOption, numberOfGifLoopsOption, beepOnFinishOption, encodingMaxRateOption, encodingBufferSizeOption, reproOption, enableLambdaInsights, logLevelOption, delayRenderTimeoutInMillisecondsOption, publicDirOption, binariesDirectoryOption, preferLosslessOption, framesOption, forSeamlessAacConcatenationOption, audioCodecOption, publicPathOption, hardwareAccelerationOption, audioLatencyHintOption, enableCrossSiteIsolationOption, imageSequencePatternOption, darkModeOption, defaultEditorOption, askAIOption, publicLicenseKeyOption, interactivityOption, keyboardShortcutsOption, forceNewStudioOption, numberOfSharedAudioTagsOption, ipv4Option, pixelFormatOption, browserExecutableOption, everyNthFrameOption, proResProfileOption, stillImageFormatOption, videoImageFormatOption, userAgentOption, disableWebSecurityOption, ignoreCertificateErrorsOption, overrideHeightOption, overrideWidthOption, overrideFpsOption, overrideDurationOption, rspackOption, outDirOption, webpackPollOption, imageSequenceOption, bundleCacheOption, envFileOption, runsOption, noOpenOption, sampleRateOption, previewSampleRateOption, } = client_1.BrowserSafeApis.options;
21
+ const { benchmarkConcurrenciesOption, concurrencyOption, offthreadVideoCacheSizeInBytesOption, x264Option, audioBitrateOption, videoBitrateOption, scaleOption, crfOption, jpegQualityOption, enforceAudioOption, overwriteOption, chromeModeOption, mutedOption, videoCodecOption, colorSpaceOption, disallowParallelEncodingOption, deleteAfterOption, folderExpiryOption, enableMultiprocessOnLinuxOption, glOption, gopSizeOption, headlessOption, numberOfGifLoopsOption, beepOnFinishOption, encodingMaxRateOption, encodingBufferSizeOption, reproOption, enableLambdaInsights, logLevelOption, delayRenderTimeoutInMillisecondsOption, publicDirOption, binariesDirectoryOption, preferLosslessOption, framesOption, forSeamlessAacConcatenationOption, audioCodecOption, publicPathOption, hardwareAccelerationOption, audioLatencyHintOption, enableCrossSiteIsolationOption, imageSequencePatternOption, darkModeOption, defaultCodingAgentOption, defaultEditorOption, askAIOption, publicLicenseKeyOption, interactivityOption, keyboardShortcutsOption, forceNewStudioOption, numberOfSharedAudioTagsOption, ipv4Option, pixelFormatOption, browserExecutableOption, everyNthFrameOption, proResProfileOption, stillImageFormatOption, videoImageFormatOption, userAgentOption, disableWebSecurityOption, ignoreCertificateErrorsOption, overrideHeightOption, overrideWidthOption, overrideFpsOption, overrideDurationOption, rspackOption, outDirOption, webpackPollOption, imageSequenceOption, bundleCacheOption, envFileOption, runsOption, noOpenOption, sampleRateOption, previewSampleRateOption, } = client_1.BrowserSafeApis.options;
22
22
  const setAllowHtmlInCanvasEnabled = (_enabled) => {
23
23
  log_1.Log.warn({ indent: false, logLevel: 'info' }, 'Config.setAllowHtmlInCanvasEnabled() is now a no-op because HTML-in-canvas is enabled by default when supported. You can remove this option from your config file.');
24
24
  };
@@ -128,6 +128,7 @@ exports.Config = {
128
128
  setEnableCrossSiteIsolation: enableCrossSiteIsolationOption.setConfig,
129
129
  setAskAIEnabled: askAIOption.setConfig,
130
130
  setPublicLicenseKey: publicLicenseKeyOption.setConfig,
131
+ setDefaultCodingAgent: defaultCodingAgentOption.setConfig,
131
132
  setDefaultEditor: defaultEditorOption.setConfig,
132
133
  setForceNewStudioEnabled: forceNewStudioOption.setConfig,
133
134
  setIPv4: ipv4Option.setConfig,
@@ -0,0 +1,10 @@
1
+ import type { ConfigFileChangeType } from '@remotion/studio-shared';
2
+ export type ConfigFileFingerprints = {
3
+ reload: string;
4
+ restart: string;
5
+ };
6
+ export declare const makeConfigFileFingerprints: (code: string) => ConfigFileFingerprints;
7
+ export declare const classifyConfigFileChange: ({ currentCode, startupFingerprints, }: {
8
+ currentCode: string;
9
+ startupFingerprints: ConfigFileFingerprints;
10
+ }) => ConfigFileChangeType;
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.classifyConfigFileChange = exports.makeConfigFileFingerprints = void 0;
4
+ const parser_1 = require("@babel/parser");
5
+ // Keep this exhaustive so every new Config method must declare its Studio lifecycle.
6
+ const configMethodLifecycles = {
7
+ overrideBundlerConfig: 'restart',
8
+ overrideDuration: 'runtime',
9
+ overrideFfmpegCommand: 'runtime',
10
+ overrideFps: 'runtime',
11
+ overrideHeight: 'runtime',
12
+ overrideRspackConfig: 'restart',
13
+ overrideWebpackConfig: 'restart',
14
+ overrideWidth: 'runtime',
15
+ setAllowHtmlInCanvasEnabled: 'runtime',
16
+ setAskAIEnabled: 'runtime',
17
+ setAudioBitrate: 'runtime',
18
+ setAudioCodec: 'runtime',
19
+ setAudioLatencyHint: 'reload',
20
+ setBeepOnFinish: 'runtime',
21
+ setBenchmarkConcurrencies: 'runtime',
22
+ setBenchmarkRuns: 'runtime',
23
+ setBinariesDirectory: 'restart',
24
+ setBrowserExecutable: 'runtime',
25
+ setBufferStateDelayInMilliseconds: 'runtime',
26
+ setBundleOutDir: 'runtime',
27
+ setCachingEnabled: 'runtime',
28
+ setChromeMode: 'runtime',
29
+ setChromiumDarkMode: 'runtime',
30
+ setChromiumDisableWebSecurity: 'runtime',
31
+ setChromiumHeadlessMode: 'runtime',
32
+ setChromiumIgnoreCertificateErrors: 'runtime',
33
+ setChromiumMultiProcessOnLinux: 'runtime',
34
+ setChromiumOpenGlRenderer: 'runtime',
35
+ setChromiumUserAgent: 'runtime',
36
+ setCodec: 'runtime',
37
+ setColorSpace: 'runtime',
38
+ setConcurrency: 'runtime',
39
+ setCrf: 'runtime',
40
+ setDefaultCodingAgent: 'runtime',
41
+ setDefaultEditor: 'runtime',
42
+ setDelayRenderTimeoutInMilliseconds: 'runtime',
43
+ setDeleteAfter: 'runtime',
44
+ setDisallowParallelEncoding: 'runtime',
45
+ setDotEnvLocation: 'restart',
46
+ setEnableCrossSiteIsolation: 'restart',
47
+ setEnableFolderExpiry: 'runtime',
48
+ setEncodingBufferSize: 'runtime',
49
+ setEncodingMaxRate: 'runtime',
50
+ setEnforceAudioTrack: 'runtime',
51
+ setEntryPoint: 'restart',
52
+ setEveryNthFrame: 'runtime',
53
+ setExperimentalRspackEnabled: 'restart',
54
+ setForSeamlessAacConcatenation: 'runtime',
55
+ setForceNewStudioEnabled: 'restart',
56
+ setFrameRange: 'runtime',
57
+ setGopSize: 'runtime',
58
+ setHardwareAcceleration: 'runtime',
59
+ setIPv4: 'restart',
60
+ setImageFormat: 'runtime',
61
+ setImageSequence: 'runtime',
62
+ setImageSequencePattern: 'runtime',
63
+ setInteractivityEnabled: 'runtime',
64
+ setJpegQuality: 'runtime',
65
+ setKeyboardShortcutsEnabled: 'runtime',
66
+ setLambdaInsights: 'runtime',
67
+ setLevel: 'restart',
68
+ setLogLevel: 'restart',
69
+ setMaxTimelineTracks: 'runtime',
70
+ setMetadata: 'runtime',
71
+ setMuted: 'runtime',
72
+ setNumberOfGifLoops: 'runtime',
73
+ setNumberOfSharedAudioTags: 'reload',
74
+ setOffthreadVideoCacheSizeInBytes: 'runtime',
75
+ setOutputLocation: 'runtime',
76
+ setOverwriteOutput: 'runtime',
77
+ setPixelFormat: 'runtime',
78
+ setPort: 'restart',
79
+ setPreferLosslessAudio: 'runtime',
80
+ setPreviewSampleRate: 'reload',
81
+ setProResProfile: 'runtime',
82
+ setPublicDir: 'restart',
83
+ setPublicLicenseKey: 'runtime',
84
+ setPublicPath: 'runtime',
85
+ setQuality: 'runtime',
86
+ setRendererPort: 'restart',
87
+ setRepro: 'runtime',
88
+ setRspack: 'restart',
89
+ setSampleRate: 'runtime',
90
+ setScale: 'runtime',
91
+ setShouldOpenBrowser: 'restart',
92
+ setStillImageFormat: 'runtime',
93
+ setStudioPort: 'restart',
94
+ setTimeoutInMilliseconds: 'runtime',
95
+ setVideoBitrate: 'runtime',
96
+ setVideoImageFormat: 'runtime',
97
+ setWebpackPollingInMilliseconds: 'restart',
98
+ setX264Preset: 'runtime',
99
+ };
100
+ const getConfigMethodsWithLifecycle = (lifecycle) => {
101
+ return new Set(Object.entries(configMethodLifecycles)
102
+ .filter(([, value]) => value === lifecycle)
103
+ .map(([methodName]) => methodName));
104
+ };
105
+ const runtimeConfigMethods = getConfigMethodsWithLifecycle('runtime');
106
+ const reloadConfigMethods = getConfigMethodsWithLifecycle('reload');
107
+ const ignoredAstProperties = new Set([
108
+ 'comments',
109
+ 'end',
110
+ 'errors',
111
+ 'extra',
112
+ 'loc',
113
+ 'start',
114
+ ]);
115
+ const getStaticPropertyName = (node) => {
116
+ var _a;
117
+ if (!node || typeof node !== 'object') {
118
+ return null;
119
+ }
120
+ const candidate = node;
121
+ if (candidate.type === 'Identifier') {
122
+ return (_a = candidate.name) !== null && _a !== void 0 ? _a : null;
123
+ }
124
+ if (candidate.type === 'StringLiteral') {
125
+ return typeof candidate.value === 'string' ? candidate.value : null;
126
+ }
127
+ return null;
128
+ };
129
+ const getConfigMethodName = (node) => {
130
+ if (!node || typeof node !== 'object') {
131
+ return null;
132
+ }
133
+ const callExpression = node;
134
+ if (callExpression.type !== 'CallExpression' ||
135
+ !callExpression.callee ||
136
+ typeof callExpression.callee !== 'object') {
137
+ return null;
138
+ }
139
+ const callee = callExpression.callee;
140
+ if (callee.type !== 'MemberExpression') {
141
+ return null;
142
+ }
143
+ const methodName = getStaticPropertyName(callee.property);
144
+ if (!methodName || !callee.object || typeof callee.object !== 'object') {
145
+ return null;
146
+ }
147
+ const configObject = callee.object;
148
+ if ((configObject.type === 'Identifier' && configObject.name === 'Config') ||
149
+ (configObject.type === 'MemberExpression' &&
150
+ getStaticPropertyName(configObject.property) === 'Config')) {
151
+ return methodName;
152
+ }
153
+ return null;
154
+ };
155
+ const isConfigRequire = (node) => {
156
+ var _a;
157
+ if (!node || typeof node !== 'object') {
158
+ return false;
159
+ }
160
+ const declarator = node;
161
+ if (declarator.type !== 'VariableDeclarator' ||
162
+ !declarator.init ||
163
+ typeof declarator.init !== 'object') {
164
+ return false;
165
+ }
166
+ const init = declarator.init;
167
+ if (init.type !== 'CallExpression' ||
168
+ !init.callee ||
169
+ typeof init.callee !== 'object' ||
170
+ init.callee.type !== 'Identifier' ||
171
+ init.callee.name !== 'require' ||
172
+ ((_a = init.arguments) === null || _a === void 0 ? void 0 : _a.length) !== 1) {
173
+ return false;
174
+ }
175
+ const source = init.arguments[0];
176
+ return ((source === null || source === void 0 ? void 0 : source.type) === 'StringLiteral' && source.value === '@remotion/cli/config');
177
+ };
178
+ const makeConfigFingerprint = ({ code, ignoredConfigMethods, }) => {
179
+ const ast = (0, parser_1.parse)(code, { sourceType: 'unambiguous' });
180
+ const omit = Symbol('omit');
181
+ const normalize = (value) => {
182
+ var _a;
183
+ if (Array.isArray(value)) {
184
+ return value
185
+ .map(normalize)
186
+ .filter((normalizedValue) => normalizedValue !== omit);
187
+ }
188
+ if (!value || typeof value !== 'object') {
189
+ return value;
190
+ }
191
+ const node = value;
192
+ const expressionConfigMethodName = getConfigMethodName(node.expression);
193
+ if (node.type === 'ExpressionStatement' &&
194
+ expressionConfigMethodName &&
195
+ ignoredConfigMethods.has(expressionConfigMethodName)) {
196
+ return omit;
197
+ }
198
+ if (node.type === 'VariableDeclaration' &&
199
+ ((_a = node.declarations) === null || _a === void 0 ? void 0 : _a.length) &&
200
+ node.declarations.every(isConfigRequire)) {
201
+ return omit;
202
+ }
203
+ const configMethodName = getConfigMethodName(value);
204
+ if (configMethodName && ignoredConfigMethods.has(configMethodName)) {
205
+ return { type: 'IgnoredConfigCall' };
206
+ }
207
+ return Object.fromEntries(Object.entries(value)
208
+ .filter(([key]) => !ignoredAstProperties.has(key))
209
+ .map(([key, child]) => [key, normalize(child)]));
210
+ };
211
+ return JSON.stringify(normalize(ast));
212
+ };
213
+ const makeConfigFileFingerprints = (code) => {
214
+ return {
215
+ reload: makeConfigFingerprint({
216
+ code,
217
+ ignoredConfigMethods: runtimeConfigMethods,
218
+ }),
219
+ restart: makeConfigFingerprint({
220
+ code,
221
+ ignoredConfigMethods: new Set([
222
+ ...runtimeConfigMethods,
223
+ ...reloadConfigMethods,
224
+ ]),
225
+ }),
226
+ };
227
+ };
228
+ exports.makeConfigFileFingerprints = makeConfigFileFingerprints;
229
+ const classifyConfigFileChange = ({ currentCode, startupFingerprints, }) => {
230
+ const currentFingerprints = (0, exports.makeConfigFileFingerprints)(currentCode);
231
+ if (currentFingerprints.restart !== startupFingerprints.restart) {
232
+ return 'restart';
233
+ }
234
+ if (currentFingerprints.reload !== startupFingerprints.reload) {
235
+ return 'reload';
236
+ }
237
+ return 'runtime';
238
+ };
239
+ exports.classifyConfigFileChange = classifyConfigFileChange;
@@ -1,5 +1,17 @@
1
1
  export declare const getLoadedConfigFile: () => string | null;
2
+ export declare const getLoadedConfigFileCode: () => string | null;
2
3
  export declare const loadConfig: (remotionRoot: string) => Promise<string | null>;
3
- export declare const reloadConfig: ({ resetConfigOptions, }: {
4
+ type ReloadConfigResult<T> = {
5
+ type: 'success';
6
+ value: T;
7
+ } | {
8
+ type: 'error';
9
+ errorMessage: string;
10
+ } | {
11
+ type: 'no-config';
12
+ };
13
+ export declare const reloadConfig: <T>({ resetConfigOptions, getConfigSnapshot, }: {
4
14
  resetConfigOptions: () => void;
5
- }) => Promise<boolean>;
15
+ getConfigSnapshot: (configFileCode: string) => T | Promise<T>;
16
+ }) => Promise<ReloadConfigResult<T>>;
17
+ export {};
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.reloadConfig = exports.loadConfig = exports.getLoadedConfigFile = void 0;
6
+ exports.reloadConfig = exports.loadConfig = exports.getLoadedConfigFileCode = exports.getLoadedConfigFile = void 0;
7
7
  const node_fs_1 = require("node:fs");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const client_1 = require("@remotion/renderer/client");
@@ -20,6 +20,11 @@ const getLoadedConfigFile = () => {
20
20
  return (_a = loadedConfigFile === null || loadedConfigFile === void 0 ? void 0 : loadedConfigFile.resolved) !== null && _a !== void 0 ? _a : null;
21
21
  };
22
22
  exports.getLoadedConfigFile = getLoadedConfigFile;
23
+ const getLoadedConfigFileCode = () => {
24
+ var _a;
25
+ return (_a = loadedConfigFile === null || loadedConfigFile === void 0 ? void 0 : loadedConfigFile.code) !== null && _a !== void 0 ? _a : null;
26
+ };
27
+ exports.getLoadedConfigFileCode = getLoadedConfigFileCode;
23
28
  const warnAboutBundlerOverride = () => {
24
29
  const useRspack = rspackOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
25
30
  const hasWebpackOverride = config_1.ConfigInternals.getWebpackOverrideFn() !==
@@ -79,9 +84,12 @@ const loadConfig = async (remotionRoot) => {
79
84
  return null;
80
85
  };
81
86
  exports.loadConfig = loadConfig;
82
- const reloadConfig = async ({ resetConfigOptions, }) => {
87
+ const logConfigReloadError = (errorMessage) => {
88
+ log_1.Log.error({ indent: false, logLevel: 'error' }, 'Could not reload the Remotion config. Keeping the previous configuration.', errorMessage);
89
+ };
90
+ const reloadConfig = async ({ resetConfigOptions, getConfigSnapshot, }) => {
83
91
  if (!loadedConfigFile) {
84
- return false;
92
+ return { type: 'no-config' };
85
93
  }
86
94
  const previousConfigFile = loadedConfigFile;
87
95
  let nextConfigFile;
@@ -89,21 +97,24 @@ const reloadConfig = async ({ resetConfigOptions, }) => {
89
97
  nextConfigFile = await (0, load_config_1.prepareConfigFile)(previousConfigFile.remotionRoot, previousConfigFile.resolved, previousConfigFile.resolved.endsWith('.js'));
90
98
  }
91
99
  catch (error) {
92
- log_1.Log.error({ indent: false, logLevel: 'error' }, 'Could not reload the Remotion config. Keeping the previous configuration.', error instanceof Error ? error.message : String(error));
93
- return false;
100
+ const errorMessage = error instanceof Error ? error.message : String(error);
101
+ logConfigReloadError(errorMessage);
102
+ return { type: 'error', errorMessage };
94
103
  }
95
104
  resetConfigOptions();
96
105
  try {
97
106
  (0, load_config_1.executeConfigFile)(nextConfigFile);
98
- loadedConfigFile = nextConfigFile;
107
+ const configSnapshot = await getConfigSnapshot(nextConfigFile.code);
99
108
  warnAboutBundlerOverride();
100
- return true;
109
+ loadedConfigFile = nextConfigFile;
110
+ return { type: 'success', value: configSnapshot };
101
111
  }
102
112
  catch (error) {
103
113
  resetConfigOptions();
104
114
  (0, load_config_1.executeConfigFile)(previousConfigFile);
105
- log_1.Log.error({ indent: false, logLevel: 'error' }, 'Could not reload the Remotion config. Keeping the previous configuration.', error instanceof Error ? error.message : String(error));
106
- return false;
115
+ const errorMessage = error instanceof Error ? error.message : String(error);
116
+ logConfigReloadError(errorMessage);
117
+ return { type: 'error', errorMessage };
107
118
  }
108
119
  };
109
120
  exports.reloadConfig = reloadConfig;
@@ -351,6 +351,21 @@ declare const benchmarkConcurrenciesOption: {
351
351
  };
352
352
  setConfig: (value: boolean) => void;
353
353
  id: "dark-mode";
354
+ }, defaultCodingAgentOption: {
355
+ name: string;
356
+ cliFlag: "coding-agent";
357
+ description: () => import("react/jsx-runtime").JSX.Element;
358
+ ssrName: null;
359
+ docLink: string;
360
+ type: "claude-code" | "codex" | "cursor" | "github-copilot" | null;
361
+ getValue: ({ commandLine }: {
362
+ commandLine: Record<string, unknown>;
363
+ }) => {
364
+ value: "claude-code" | "codex" | "cursor" | "github-copilot" | null;
365
+ source: string;
366
+ };
367
+ setConfig(value: "claude-code" | "codex" | "cursor" | "github-copilot" | null): void;
368
+ id: "coding-agent";
354
369
  }, defaultEditorOption: {
355
370
  name: string;
356
371
  cliFlag: "editor";
@@ -1190,6 +1205,7 @@ export type CommandLineOptions = {
1190
1205
  [envFileOption.cliFlag]: TypeOfOption<typeof envFileOption>;
1191
1206
  [ignoreCertificateErrorsOption.cliFlag]: TypeOfOption<typeof ignoreCertificateErrorsOption> | null;
1192
1207
  [darkModeOption.cliFlag]: TypeOfOption<typeof darkModeOption> | null;
1208
+ [defaultCodingAgentOption.cliFlag]: TypeOfOption<typeof defaultCodingAgentOption>;
1193
1209
  [defaultEditorOption.cliFlag]: TypeOfOption<typeof defaultEditorOption>;
1194
1210
  [disableWebSecurityOption.cliFlag]: TypeOfOption<typeof disableWebSecurityOption> | null;
1195
1211
  [everyNthFrameOption.cliFlag]: TypeOfOption<typeof everyNthFrameOption>;
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.quietFlagProvided = exports.parsedCli = exports.BooleanFlags = void 0;
7
7
  const client_1 = require("@remotion/renderer/client");
8
8
  const minimist_1 = __importDefault(require("minimist"));
9
- const { benchmarkConcurrenciesOption, beepOnFinishOption, colorSpaceOption, concurrencyOption, disallowParallelEncodingOption, offthreadVideoCacheSizeInBytesOption, encodingBufferSizeOption, encodingMaxRateOption, deleteAfterOption, folderExpiryOption, enableMultiprocessOnLinuxOption, numberOfGifLoopsOption, x264Option, enforceAudioOption, jpegQualityOption, audioBitrateOption, videoBitrateOption, audioCodecOption, publicPathOption, audioLatencyHintOption, darkModeOption, defaultEditorOption, publicLicenseKeyOption, forceNewStudioOption, numberOfSharedAudioTagsOption, ipv4Option, pixelFormatOption, browserExecutableOption, everyNthFrameOption, proResProfileOption, userAgentOption, disableWebSecurityOption, ignoreCertificateErrorsOption, overrideHeightOption, overrideWidthOption, overrideFpsOption, overrideDurationOption, outDirOption, packageManagerOption, webpackPollOption, keyboardShortcutsOption, interactivityOption, imageSequencePatternOption, scaleOption, overwriteOption, crfOption, logLevelOption, videoCodecOption, stillFrameOption, imageSequenceOption, versionFlagOption, bundleCacheOption, envFileOption, glOption, gopSizeOption, runsOption, reproOption, mutedOption, headlessOption, disableGitSourceOption, delayRenderTimeoutInMillisecondsOption, framesOption, forSeamlessAacConcatenationOption, isProductionOption, noOpenOption, portOption, propsOption, configOption, browserOption, sampleRateOption, previewSampleRateOption, rspackOption, skipSkillsOption, } = client_1.BrowserSafeApis.options;
9
+ const { benchmarkConcurrenciesOption, beepOnFinishOption, colorSpaceOption, concurrencyOption, disallowParallelEncodingOption, offthreadVideoCacheSizeInBytesOption, encodingBufferSizeOption, encodingMaxRateOption, deleteAfterOption, folderExpiryOption, enableMultiprocessOnLinuxOption, numberOfGifLoopsOption, x264Option, enforceAudioOption, jpegQualityOption, audioBitrateOption, videoBitrateOption, audioCodecOption, publicPathOption, audioLatencyHintOption, darkModeOption, defaultCodingAgentOption, defaultEditorOption, publicLicenseKeyOption, forceNewStudioOption, numberOfSharedAudioTagsOption, ipv4Option, pixelFormatOption, browserExecutableOption, everyNthFrameOption, proResProfileOption, userAgentOption, disableWebSecurityOption, ignoreCertificateErrorsOption, overrideHeightOption, overrideWidthOption, overrideFpsOption, overrideDurationOption, outDirOption, packageManagerOption, webpackPollOption, keyboardShortcutsOption, interactivityOption, imageSequencePatternOption, scaleOption, overwriteOption, crfOption, logLevelOption, videoCodecOption, stillFrameOption, imageSequenceOption, versionFlagOption, bundleCacheOption, envFileOption, glOption, gopSizeOption, runsOption, reproOption, mutedOption, headlessOption, disableGitSourceOption, delayRenderTimeoutInMillisecondsOption, framesOption, forSeamlessAacConcatenationOption, isProductionOption, noOpenOption, portOption, propsOption, configOption, browserOption, sampleRateOption, previewSampleRateOption, rspackOption, skipSkillsOption, } = client_1.BrowserSafeApis.options;
10
10
  exports.BooleanFlags = [
11
11
  overwriteOption.cliFlag,
12
12
  imageSequenceOption.cliFlag,
package/dist/studio.js CHANGED
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.studioCommand = void 0;
4
4
  const client_1 = require("@remotion/renderer/client");
5
5
  const studio_server_1 = require("@remotion/studio-server");
6
+ const studio_shared_1 = require("@remotion/studio-shared");
6
7
  const chalk_1 = require("./chalk");
7
8
  const config_1 = require("./config");
9
+ const config_file_change_1 = require("./config-file-change");
8
10
  const convert_entry_point_to_serve_url_1 = require("./convert-entry-point-to-serve-url");
9
11
  const entry_point_1 = require("./entry-point");
10
12
  const get_config_file_name_1 = require("./get-config-file-name");
@@ -15,7 +17,7 @@ const get_render_defaults_1 = require("./get-render-defaults");
15
17
  const log_1 = require("./log");
16
18
  const parsed_cli_1 = require("./parsed-cli");
17
19
  const queue_1 = require("./render-queue/queue");
18
- const { binariesDirectoryOption, publicDirOption, disableGitSourceOption, enableCrossSiteIsolationOption, askAIOption, interactivityOption, keyboardShortcutsOption, forceNewStudioOption, numberOfSharedAudioTagsOption, audioLatencyHintOption, ipv4Option, rspackOption, webpackPollOption, noOpenOption, portOption, browserOption, previewSampleRateOption, defaultEditorOption, } = client_1.BrowserSafeApis.options;
20
+ const { binariesDirectoryOption, publicDirOption, disableGitSourceOption, enableCrossSiteIsolationOption, askAIOption, interactivityOption, keyboardShortcutsOption, forceNewStudioOption, numberOfSharedAudioTagsOption, audioLatencyHintOption, ipv4Option, rspackOption, webpackPollOption, noOpenOption, portOption, browserOption, previewSampleRateOption, defaultCodingAgentOption, defaultEditorOption, } = client_1.BrowserSafeApis.options;
19
21
  const studioCommand = async (remotionRoot, args, logLevel) => {
20
22
  var _a, _b, _c;
21
23
  const { file, reason } = (0, entry_point_1.findEntryPoint)({
@@ -35,36 +37,6 @@ const studioCommand = async (remotionRoot, args, logLevel) => {
35
37
  const fullEntryPath = (0, convert_entry_point_to_serve_url_1.convertEntryPointToServeUrl)(file);
36
38
  studio_server_1.StudioServerInternals.setFileWatcherRegistry(studio_server_1.StudioServerInternals.createFileWatcherRegistry());
37
39
  const configFile = (0, get_config_file_name_1.getLoadedConfigFile)();
38
- if (configFile) {
39
- let isReloadingConfig = false;
40
- studio_server_1.StudioServerInternals.installFileWatcher({
41
- file: configFile,
42
- existenceOnly: false,
43
- onChange: async () => {
44
- if (isReloadingConfig) {
45
- return;
46
- }
47
- isReloadingConfig = true;
48
- try {
49
- const configWasReloaded = await (0, get_config_file_name_1.reloadConfig)({
50
- resetConfigOptions: config_1.ConfigInternals.resetConfigOptions,
51
- });
52
- if (!configWasReloaded) {
53
- return;
54
- }
55
- log_1.Log.info({ indent: false, logLevel }, chalk_1.chalk.blue('Config file changed. Reloading Studio'));
56
- studio_server_1.StudioServerInternals.waitForLiveEventsListener().then((listener) => {
57
- listener.sendEventToClient({
58
- type: 'config-file-changed',
59
- });
60
- });
61
- }
62
- finally {
63
- isReloadingConfig = false;
64
- }
65
- },
66
- });
67
- }
68
40
  let inputProps = (0, get_input_props_1.getInputProps)((newProps) => {
69
41
  studio_server_1.StudioServerInternals.waitForLiveEventsListener().then((listener) => {
70
42
  inputProps = newProps;
@@ -118,7 +90,79 @@ const studioCommand = async (remotionRoot, args, logLevel) => {
118
90
  const getNumberOfAudioTags = () => numberOfSharedAudioTagsOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
119
91
  const getAudioLatencyHint = () => audioLatencyHintOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
120
92
  const getPreviewSampleRate = () => previewSampleRateOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
93
+ const getDefaultCodingAgent = () => defaultCodingAgentOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
121
94
  const getDefaultEditor = () => defaultEditorOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value;
95
+ const startupConfigCode = (0, get_config_file_name_1.getLoadedConfigFileCode)();
96
+ if (configFile && startupConfigCode) {
97
+ let isReloadingConfig = false;
98
+ let startupConfigFingerprints = null;
99
+ const sendConfigFileReloadError = (errorMessage) => {
100
+ studio_server_1.StudioServerInternals.waitForLiveEventsListener().then((listener) => {
101
+ listener.sendEventToClient({
102
+ type: 'config-file-reload-failed',
103
+ errorMessage,
104
+ });
105
+ });
106
+ };
107
+ studio_server_1.StudioServerInternals.installFileWatcher({
108
+ file: configFile,
109
+ existenceOnly: false,
110
+ onChange: async () => {
111
+ if (isReloadingConfig) {
112
+ return;
113
+ }
114
+ isReloadingConfig = true;
115
+ try {
116
+ const reloadResult = await (0, get_config_file_name_1.reloadConfig)({
117
+ resetConfigOptions: config_1.ConfigInternals.resetConfigOptions,
118
+ getConfigSnapshot: async (currentConfigCode) => {
119
+ startupConfigFingerprints !== null && startupConfigFingerprints !== void 0 ? startupConfigFingerprints : (startupConfigFingerprints = (0, config_file_change_1.makeConfigFileFingerprints)(startupConfigCode));
120
+ const configFileChangeType = (0, config_file_change_1.classifyConfigFileChange)({
121
+ currentCode: currentConfigCode,
122
+ startupFingerprints: startupConfigFingerprints,
123
+ });
124
+ return {
125
+ changeType: configFileChangeType,
126
+ renderDefaults: (0, get_render_defaults_1.getRenderDefaults)(logLevel),
127
+ studioRuntimeConfig: getStudioRuntimeConfig(),
128
+ editorName: await studio_server_1.StudioServerInternals.getEditorName({
129
+ getDefaultEditor,
130
+ logLevel,
131
+ }),
132
+ };
133
+ },
134
+ });
135
+ if (reloadResult.type === 'no-config') {
136
+ return;
137
+ }
138
+ if (reloadResult.type === 'error') {
139
+ sendConfigFileReloadError(reloadResult.errorMessage);
140
+ return;
141
+ }
142
+ const { changeType, renderDefaults, studioRuntimeConfig, editorName } = reloadResult.value;
143
+ const message = (0, studio_shared_1.getConfigFileChangeMessage)(changeType);
144
+ log_1.Log.info({ indent: false, logLevel }, chalk_1.chalk.blue(message));
145
+ studio_server_1.StudioServerInternals.waitForLiveEventsListener().then((listener) => {
146
+ listener.sendEventToClient({
147
+ type: 'config-file-changed',
148
+ changeType,
149
+ renderDefaults,
150
+ studioRuntimeConfig,
151
+ editorName,
152
+ });
153
+ });
154
+ }
155
+ catch (error) {
156
+ const errorMessage = error instanceof Error ? error.message : String(error);
157
+ log_1.Log.error({ indent: false, logLevel: 'error' }, errorMessage);
158
+ sendConfigFileReloadError(errorMessage);
159
+ }
160
+ finally {
161
+ isReloadingConfig = false;
162
+ }
163
+ },
164
+ });
165
+ }
122
166
  const result = await studio_server_1.StudioServerInternals.startStudio({
123
167
  previewEntry: require.resolve('@remotion/studio/previewEntry'),
124
168
  browserArgs: parsed_cli_1.parsedCli['browser-args'],
@@ -158,6 +202,7 @@ const studioCommand = async (remotionRoot, args, logLevel) => {
158
202
  forceIPv4: ipv4Option.getValue({ commandLine: parsed_cli_1.parsedCli }).value,
159
203
  getAudioLatencyHint,
160
204
  getPreviewSampleRate,
205
+ getDefaultCodingAgent,
161
206
  getDefaultEditor,
162
207
  enableCrossSiteIsolation,
163
208
  forceNew: forceNewStudioOption.getValue({ commandLine: parsed_cli_1.parsedCli }).value,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/cli"
4
4
  },
5
5
  "name": "@remotion/cli",
6
- "version": "4.0.505",
6
+ "version": "4.0.506",
7
7
  "description": "Control Remotion features using the `npx remotion` command",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
@@ -36,18 +36,19 @@
36
36
  "author": "Jonny Burger <jonny@remotion.dev>",
37
37
  "license": "SEE LICENSE IN LICENSE.md",
38
38
  "dependencies": {
39
- "@remotion/bundler": "4.0.505",
40
- "@remotion/media-utils": "4.0.505",
41
- "@remotion/player": "4.0.505",
42
- "@remotion/renderer": "4.0.505",
43
- "@remotion/studio-shared": "4.0.505",
44
- "@remotion/studio-server": "4.0.505",
45
- "@remotion/studio": "4.0.505",
39
+ "@babel/parser": "7.24.1",
40
+ "@remotion/bundler": "4.0.506",
41
+ "@remotion/media-utils": "4.0.506",
42
+ "@remotion/player": "4.0.506",
43
+ "@remotion/renderer": "4.0.506",
44
+ "@remotion/studio-shared": "4.0.506",
45
+ "@remotion/studio-server": "4.0.506",
46
+ "@remotion/studio": "4.0.506",
46
47
  "dotenv": "17.3.1",
47
48
  "minimist": "1.2.6",
48
49
  "prompts": "2.4.2",
49
50
  "semver": "7.5.3",
50
- "remotion": "4.0.505"
51
+ "remotion": "4.0.506"
51
52
  },
52
53
  "peerDependencies": {
53
54
  "react": ">=16.8.0",
@@ -59,14 +60,14 @@
59
60
  "@types/prettier": "2.7.2",
60
61
  "@types/semver": "7.5.3",
61
62
  "@types/node": "20.12.14",
62
- "@remotion/zod-types": "4.0.505",
63
- "@remotion/tailwind-v4": "4.0.505",
64
- "@remotion/enable-scss": "4.0.505",
65
- "@remotion/skia": "4.0.505",
63
+ "@remotion/zod-types": "4.0.506",
64
+ "@remotion/tailwind-v4": "4.0.506",
65
+ "@remotion/enable-scss": "4.0.506",
66
+ "@remotion/skia": "4.0.506",
66
67
  "react": "19.2.3",
67
68
  "react-dom": "19.2.3",
68
69
  "zod": "4.4.3",
69
- "@remotion/eslint-config-internal": "4.0.505",
70
+ "@remotion/eslint-config-internal": "4.0.506",
70
71
  "eslint": "9.19.0",
71
72
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
72
73
  },