@remotion/studio-server 4.0.534 → 4.0.536

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.
Files changed (103) hide show
  1. package/dist/file-watcher.js +2 -0
  2. package/dist/helpers/app-discovery.d.ts +9 -0
  3. package/dist/helpers/app-discovery.js +61 -0
  4. package/dist/helpers/open-in-app.d.ts +13 -0
  5. package/dist/helpers/open-in-app.js +72 -0
  6. package/dist/helpers/open-in-editor.js +7 -6
  7. package/dist/helpers/recently-used-apps.d.ts +9 -0
  8. package/dist/helpers/recently-used-apps.js +63 -0
  9. package/dist/helpers/resolve-composition-component.d.ts +1 -2
  10. package/dist/helpers/resolve-composition-component.js +1 -3
  11. package/dist/preview-server/api-routes.js +4 -5
  12. package/dist/preview-server/live-events.d.ts +1 -0
  13. package/dist/preview-server/live-events.js +12 -1
  14. package/dist/preview-server/routes/app-info.d.ts +3 -0
  15. package/dist/preview-server/routes/app-info.js +16 -0
  16. package/dist/preview-server/routes/default-coding-agent.d.ts +1 -2
  17. package/dist/preview-server/routes/default-coding-agent.js +10 -20
  18. package/dist/preview-server/routes/default-editor.js +9 -33
  19. package/dist/preview-server/routes/element-install-plan.js +5 -0
  20. package/dist/preview-server/routes/insert-basic-captions.js +2 -2
  21. package/dist/preview-server/routes/insert-composition-element.js +14 -6
  22. package/dist/preview-server/routes/insert-element.js +46 -14
  23. package/dist/preview-server/routes/open-in-editor.d.ts +1 -1
  24. package/dist/preview-server/routes/open-in-editor.js +2 -56
  25. package/dist/preview-server/routes/redo.js +2 -1
  26. package/dist/preview-server/routes/source-file-write-queue.d.ts +1 -1
  27. package/dist/preview-server/routes/undo.js +2 -1
  28. package/dist/preview-server/routes/update-config.js +12 -5
  29. package/dist/preview-server/studio-protocol/handle-element-library.js +14 -0
  30. package/dist/preview-server/studio-protocol/handle-install.js +2 -1
  31. package/dist/preview-server/undo-stack.js +1 -0
  32. package/dist/preview-server/watch-ignore-next-change.d.ts +1 -0
  33. package/dist/preview-server/watch-ignore-next-change.js +15 -2
  34. package/dist/start-studio.js +6 -3
  35. package/dist/studio-shortcuts.d.ts +13 -0
  36. package/dist/studio-shortcuts.js +257 -0
  37. package/package.json +8 -8
  38. package/dist/canvas-capture/generate-canvas-capture-composition.d.ts +0 -14
  39. package/dist/canvas-capture/generate-canvas-capture-composition.js +0 -239
  40. package/dist/codemods/add-effect.d.ts +0 -1
  41. package/dist/codemods/add-effect.js +0 -8
  42. package/dist/codemods/apply-codemod-to-file.d.ts +0 -7
  43. package/dist/codemods/apply-codemod-to-file.js +0 -171
  44. package/dist/codemods/apply-visual-control.d.ts +0 -8
  45. package/dist/codemods/apply-visual-control.js +0 -89
  46. package/dist/codemods/delete-effect.d.ts +0 -1
  47. package/dist/codemods/delete-effect.js +0 -6
  48. package/dist/codemods/delete-jsx-node.d.ts +0 -22
  49. package/dist/codemods/delete-jsx-node.js +0 -17
  50. package/dist/codemods/delete-jsx-nodes.d.ts +0 -13
  51. package/dist/codemods/delete-jsx-nodes.js +0 -10
  52. package/dist/codemods/duplicate-composition.d.ts +0 -2
  53. package/dist/codemods/duplicate-composition.js +0 -64
  54. package/dist/codemods/duplicate-effect.d.ts +0 -1
  55. package/dist/codemods/duplicate-effect.js +0 -6
  56. package/dist/codemods/duplicate-jsx-node.d.ts +0 -25
  57. package/dist/codemods/duplicate-jsx-node.js +0 -26
  58. package/dist/codemods/format-file-content.d.ts +0 -7
  59. package/dist/codemods/format-file-content.js +0 -80
  60. package/dist/codemods/format-inline-content.d.ts +0 -18
  61. package/dist/codemods/format-inline-content.js +0 -78
  62. package/dist/codemods/insert-video-layers.d.ts +0 -11
  63. package/dist/codemods/insert-video-layers.js +0 -5
  64. package/dist/codemods/recast-mods.d.ts +0 -13
  65. package/dist/codemods/recast-mods.js +0 -902
  66. package/dist/codemods/reorder-effect.d.ts +0 -1
  67. package/dist/codemods/reorder-effect.js +0 -5
  68. package/dist/codemods/reorder-sequence.d.ts +0 -1
  69. package/dist/codemods/reorder-sequence.js +0 -5
  70. package/dist/codemods/simple-diff.d.ts +0 -5
  71. package/dist/codemods/simple-diff.js +0 -39
  72. package/dist/codemods/split-jsx-sequence.d.ts +0 -27
  73. package/dist/codemods/split-jsx-sequence.js +0 -19
  74. package/dist/codemods/split-video-from-audio.d.ts +0 -1
  75. package/dist/codemods/split-video-from-audio.js +0 -5
  76. package/dist/codemods/update-default-props.d.ts +0 -1
  77. package/dist/codemods/update-default-props.js +0 -6
  78. package/dist/codemods/update-inline-caption-patches.d.ts +0 -1
  79. package/dist/codemods/update-inline-caption-patches.js +0 -5
  80. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.d.ts +0 -1
  81. package/dist/codemods/update-keyframes/ensure-imports-and-frame-hook.js +0 -7
  82. package/dist/open-browser-shortcut.d.ts +0 -9
  83. package/dist/open-browser-shortcut.js +0 -121
  84. package/dist/preview-server/hot-middleware/types.d.ts +0 -2
  85. package/dist/preview-server/hot-middleware/types.js +0 -2
  86. package/dist/preview-server/routes/apply-codemod.d.ts +0 -4
  87. package/dist/preview-server/routes/apply-codemod.js +0 -272
  88. package/dist/preview-server/routes/delete-jsx-node.d.ts +0 -3
  89. package/dist/preview-server/routes/delete-jsx-node.js +0 -126
  90. package/dist/preview-server/routes/delete-jsx-nodes.d.ts +0 -3
  91. package/dist/preview-server/routes/delete-jsx-nodes.js +0 -137
  92. package/dist/preview-server/routes/duplicate-jsx-node.d.ts +0 -3
  93. package/dist/preview-server/routes/duplicate-jsx-node.js +0 -118
  94. package/dist/preview-server/routes/insert-jsx-element.d.ts +0 -3
  95. package/dist/preview-server/routes/insert-jsx-element.js +0 -231
  96. package/dist/preview-server/routes/insert-video-layers.d.ts +0 -3
  97. package/dist/preview-server/routes/insert-video-layers.js +0 -68
  98. package/dist/preview-server/routes/split-jsx-sequence.d.ts +0 -3
  99. package/dist/preview-server/routes/split-jsx-sequence.js +0 -117
  100. package/dist/preview-server/routes/update-public-license.d.ts +0 -11
  101. package/dist/preview-server/routes/update-public-license.js +0 -97
  102. package/dist/preview-server/routes/wrap-jsx-node.d.ts +0 -3
  103. package/dist/preview-server/routes/wrap-jsx-node.js +0 -97
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.writeFileAndNotifyFileWatchers = exports.installFileWatcher = exports.getFileWatcherRegistry = exports.setFileWatcherRegistry = exports.createFileWatcherRegistry = void 0;
37
37
  const node_fs_1 = __importStar(require("node:fs"));
38
+ const watch_ignore_next_change_1 = require("./preview-server/watch-ignore-next-change");
38
39
  const getRegistryKey = (file, existenceOnly) => existenceOnly ? `${file}\0existence-only` : file;
39
40
  const createFileWatcherRegistry = () => {
40
41
  const sharedWatchers = new Map();
@@ -130,6 +131,7 @@ const createFileWatcherRegistry = () => {
130
131
  };
131
132
  const _writeFileAndNotifyFileWatchers = ({ file, content, originatorClientId, metadata, }) => {
132
133
  var _a;
134
+ (0, watch_ignore_next_change_1.prepareBundlerForFileWrite)(file);
133
135
  (0, node_fs_1.writeFileSync)(file, content);
134
136
  const shared = sharedWatchers.get(getRegistryKey(file, false));
135
137
  if (!shared) {
@@ -0,0 +1,9 @@
1
+ import type { DefaultEditor } from '@remotion/renderer';
2
+ import type { GetDefaultEditorInfoResponse } from '@remotion/studio-shared';
3
+ export declare const getAppDiscovery: () => Promise<{
4
+ installedEditors: readonly import("./editor-registry").InstalledEditor[];
5
+ installedCodingAgents: readonly import("./coding-agent-registry").InstalledCodingAgent[];
6
+ runningEditors: readonly ("cursor" | "sublime-text" | "vscode" | "vscodium" | "webstorm" | "windsurf" | "zed")[];
7
+ runningCodingAgents: readonly ("claude-code" | "codex" | "copilot" | "cursor")[];
8
+ }>;
9
+ export declare const getEditorInfo: (configuredEditor: DefaultEditor | null) => Promise<GetDefaultEditorInfoResponse>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getEditorInfo = exports.getAppDiscovery = void 0;
4
+ const coding_agent_registry_1 = require("./coding-agent-registry");
5
+ const custom_editor_1 = require("./custom-editor");
6
+ const editor_registry_1 = require("./editor-registry");
7
+ let appDiscovery = null;
8
+ const discoverApps = async () => {
9
+ const [installedEditors, installedCodingAgents] = await Promise.all([
10
+ (0, editor_registry_1.getAvailableEditors)(),
11
+ (0, coding_agent_registry_1.getAvailableCodingAgents)(),
12
+ ]);
13
+ const [runningEditors, runningCodingAgents] = await Promise.all([
14
+ (0, editor_registry_1.getRunningEditors)(installedEditors),
15
+ (0, coding_agent_registry_1.getRunningCodingAgents)(installedCodingAgents),
16
+ ]);
17
+ return {
18
+ installedEditors,
19
+ installedCodingAgents,
20
+ runningEditors,
21
+ runningCodingAgents,
22
+ };
23
+ };
24
+ // The terminal helper and Studio requests share the same in-flight discovery
25
+ // and process snapshot. Configuration and app history are read separately.
26
+ const getAppDiscovery = () => {
27
+ appDiscovery !== null && appDiscovery !== void 0 ? appDiscovery : (appDiscovery = discoverApps());
28
+ return appDiscovery;
29
+ };
30
+ exports.getAppDiscovery = getAppDiscovery;
31
+ const getEditorInfo = async (configuredEditor) => {
32
+ const { installedEditors, runningEditors } = await (0, exports.getAppDiscovery)();
33
+ const customEditor = configuredEditor &&
34
+ typeof configuredEditor === 'object' &&
35
+ (0, custom_editor_1.resolveCustomEditorExecutable)(configuredEditor)
36
+ ? configuredEditor
37
+ : null;
38
+ return {
39
+ defaultEditor: configuredEditor && typeof configuredEditor === 'object'
40
+ ? 'custom'
41
+ : configuredEditor,
42
+ runningEditors,
43
+ installedEditors: [
44
+ ...installedEditors.map(({ id, name, nameWithType }) => ({
45
+ id,
46
+ name,
47
+ nameWithType,
48
+ })),
49
+ ...(customEditor
50
+ ? [
51
+ {
52
+ id: 'custom',
53
+ name: customEditor.name,
54
+ nameWithType: customEditor.name,
55
+ },
56
+ ]
57
+ : []),
58
+ ],
59
+ };
60
+ };
61
+ exports.getEditorInfo = getEditorInfo;
@@ -0,0 +1,13 @@
1
+ import { type DefaultEditor } from '@remotion/renderer';
2
+ import type { OpenInCodingAgentRequest, OpenInCodingAgentResponse, OpenInEditorRequest, OpenInEditorResponse } from '@remotion/studio-shared';
3
+ export declare const openInEditor: ({ input, remotionRoot, logLevel, getDefaultEditor, }: {
4
+ input: OpenInEditorRequest;
5
+ remotionRoot: string;
6
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
7
+ getDefaultEditor: () => DefaultEditor | null;
8
+ }) => Promise<OpenInEditorResponse>;
9
+ export declare const openInCodingAgent: ({ input, logLevel, remotionRoot, }: {
10
+ input: OpenInCodingAgentRequest;
11
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
12
+ remotionRoot: string;
13
+ }) => Promise<OpenInCodingAgentResponse>;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.openInCodingAgent = exports.openInEditor = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const renderer_1 = require("@remotion/renderer");
9
+ const coding_agent_registry_1 = require("./coding-agent-registry");
10
+ const custom_editor_1 = require("./custom-editor");
11
+ const open_in_editor_1 = require("./open-in-editor");
12
+ const resolve_editor_1 = require("./resolve-editor");
13
+ const openInEditor = async ({ input, remotionRoot, logLevel, getDefaultEditor, }) => {
14
+ try {
15
+ if (!('stack' in input)) {
16
+ throw new TypeError('Need to pass stack');
17
+ }
18
+ const { stack } = input;
19
+ if (input.editorId !== null &&
20
+ input.editorId !== 'custom' &&
21
+ !renderer_1.defaultEditorIds.includes(input.editorId)) {
22
+ return { success: false };
23
+ }
24
+ const editor = await (0, resolve_editor_1.resolveEditor)({
25
+ defaultEditor: getDefaultEditor(),
26
+ logLevel,
27
+ preferredEditor: input.editorId,
28
+ });
29
+ if (!editor) {
30
+ return { success: false };
31
+ }
32
+ const fileName = node_path_1.default.resolve(remotionRoot, stack.originalFileName);
33
+ const didOpen = editor.type === 'custom'
34
+ ? await (0, custom_editor_1.launchCustomEditor)({
35
+ editor: editor.editor,
36
+ resolvedExecutable: editor,
37
+ targetPath: fileName,
38
+ lineNumber: stack.originalLineNumber,
39
+ columnNumber: stack.originalColumnNumber,
40
+ logLevel,
41
+ spawnProcess: null,
42
+ })
43
+ : await (0, open_in_editor_1.launchEditor)({
44
+ colNumber: stack.originalColumnNumber,
45
+ editor,
46
+ fileName,
47
+ lineNumber: stack.originalLineNumber,
48
+ vsCodeNewWindow: false,
49
+ logLevel,
50
+ }, remotionRoot);
51
+ return { success: didOpen };
52
+ }
53
+ catch (_a) {
54
+ return { success: false };
55
+ }
56
+ };
57
+ exports.openInEditor = openInEditor;
58
+ const openInCodingAgent = async ({ input, logLevel, remotionRoot, }) => {
59
+ const codingAgent = (await (0, coding_agent_registry_1.getAvailableCodingAgents)()).find((agent) => agent.id === input.codingAgentId);
60
+ if (!codingAgent) {
61
+ return { success: false };
62
+ }
63
+ return {
64
+ success: await (0, coding_agent_registry_1.launchCodingAgent)({
65
+ codingAgent,
66
+ projectPath: remotionRoot,
67
+ logLevel,
68
+ prompt: input.prompt,
69
+ }),
70
+ };
71
+ };
72
+ exports.openInCodingAgent = openInCodingAgent;
@@ -382,9 +382,8 @@ async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNew
382
382
  if (editor.command.toLowerCase() === 'none') {
383
383
  return false;
384
384
  }
385
- let folderToOpen = isVsCodeDerivative(editor.command) && !node_fs_1.default.statSync(fileName).isDirectory()
386
- ? projectFolder
387
- : null;
385
+ const isDirectory = node_fs_1.default.statSync(fileName).isDirectory();
386
+ let folderToOpen = isVsCodeDerivative(editor.command) && !isDirectory ? projectFolder : null;
388
387
  if (process.platform === 'linux' &&
389
388
  fileName.startsWith('/mnt/') &&
390
389
  /Microsoft/i.test(node_os_1.default.release())) {
@@ -417,7 +416,7 @@ async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNew
417
416
  }
418
417
  const shouldOpenVsCodeNewWindow = isVsCodeDerivative(editor.command) && vsCodeNewWindow;
419
418
  // The file URL cannot specify both a workspace folder and a source location.
420
- if (!shouldOpenVsCodeNewWindow && folderToOpen === null) {
419
+ if (!shouldOpenVsCodeNewWindow && folderToOpen === null && !isDirectory) {
421
420
  const result = (0, open_in_editor_url_scheme_1.openInEditorViaUrlScheme)({
422
421
  editor: editor.command,
423
422
  fileName,
@@ -433,13 +432,15 @@ async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNew
433
432
  }
434
433
  const args = shouldOpenVsCodeNewWindow
435
434
  ? ['--new-window', fileName]
436
- : lineNumber
435
+ : lineNumber && !isDirectory
437
436
  ? getArgumentsForLineNumber(editor.command, fileName, String(lineNumber), colNumber)
438
437
  : [fileName];
439
438
  if (folderToOpen !== null) {
440
439
  args.unshift(folderToOpen);
441
440
  }
442
- if (process.platform === 'darwin' && folderToOpen !== null) {
441
+ if (process.platform === 'darwin' &&
442
+ isVsCodeDerivative(editor.command) &&
443
+ (folderToOpen !== null || isDirectory)) {
443
444
  const applicationPath = (_a = editor.process.match(/^(.*?\.app)\/Contents\//)) === null || _a === void 0 ? void 0 : _a[1];
444
445
  if (applicationPath && node_fs_1.default.existsSync(applicationPath)) {
445
446
  // Match the CLI's native macOS launch without starting its Node.js wrapper.
@@ -0,0 +1,9 @@
1
+ export declare const subscribeToRecentlyUsedApps: ({ remotionRoot, onChange, }: {
2
+ remotionRoot: string;
3
+ onChange: () => void;
4
+ }) => () => void;
5
+ export declare const getRecentlyUsedApps: ({ remotionRoot, type, recentlyUsedIds, }: {
6
+ remotionRoot: string;
7
+ type: "coding-agent" | "editor";
8
+ recentlyUsedIds: readonly string[] | null;
9
+ }) => Promise<readonly string[]>;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getRecentlyUsedApps = exports.subscribeToRecentlyUsedApps = void 0;
7
+ const promises_1 = require("node:fs/promises");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const renderer_1 = require("@remotion/renderer");
10
+ const histories = new Map();
11
+ const historyListeners = new Set();
12
+ const subscribeToRecentlyUsedApps = ({ remotionRoot, onChange, }) => {
13
+ const listener = { remotionRoot, onChange };
14
+ historyListeners.add(listener);
15
+ return () => {
16
+ historyListeners.delete(listener);
17
+ };
18
+ };
19
+ exports.subscribeToRecentlyUsedApps = subscribeToRecentlyUsedApps;
20
+ const getRecentlyUsedApps = ({ remotionRoot, type, recentlyUsedIds, }) => {
21
+ var _a;
22
+ const filePath = node_path_1.default.join(remotionRoot, 'node_modules', '.cache', 'remotion', `recently-used-${type}s.json`);
23
+ const allowedIds = type === 'editor' ? [...renderer_1.defaultEditorIds, 'custom'] : renderer_1.defaultCodingAgentIds;
24
+ const previous = (_a = histories.get(filePath)) !== null && _a !== void 0 ? _a : (async () => {
25
+ try {
26
+ const stored = JSON.parse(await (0, promises_1.readFile)(filePath, 'utf8'));
27
+ return Array.isArray(stored)
28
+ ? [
29
+ ...new Set(stored.filter((id) => allowedIds.includes(id))),
30
+ ]
31
+ : [];
32
+ }
33
+ catch (_a) {
34
+ return [];
35
+ }
36
+ })();
37
+ const history = previous.then(async (ids) => {
38
+ if (recentlyUsedIds === null) {
39
+ return ids;
40
+ }
41
+ const updatedIds = [
42
+ ...new Set(recentlyUsedIds.filter((id) => allowedIds.includes(id))),
43
+ ];
44
+ if (JSON.stringify(ids) !== JSON.stringify(updatedIds)) {
45
+ try {
46
+ await (0, promises_1.mkdir)(node_path_1.default.dirname(filePath), { recursive: true });
47
+ await (0, promises_1.writeFile)(filePath, JSON.stringify(updatedIds));
48
+ }
49
+ catch (_a) {
50
+ // Keep the history in memory when the project cache is not writable.
51
+ }
52
+ historyListeners.forEach((listener) => {
53
+ if (listener.remotionRoot === remotionRoot) {
54
+ listener.onChange();
55
+ }
56
+ });
57
+ }
58
+ return updatedIds;
59
+ });
60
+ histories.set(filePath, history);
61
+ return history;
62
+ };
63
+ exports.getRecentlyUsedApps = getRecentlyUsedApps;
@@ -12,13 +12,12 @@ export declare const resolveCompositionComponent: ({ remotionRoot, compositionFi
12
12
  compositionFile: string;
13
13
  compositionId: string;
14
14
  }) => Promise<ResolvedCompositionComponent>;
15
- export declare const insertJsxElementIntoComposition: ({ remotionRoot, compositionFile, compositionId, element, from, premountFor, prettierConfigOverride, wrapInSequence, sourceFileOverrides, }: {
15
+ export declare const insertJsxElementIntoComposition: ({ remotionRoot, compositionFile, compositionId, element, from, prettierConfigOverride, wrapInSequence, sourceFileOverrides, }: {
16
16
  remotionRoot: string;
17
17
  compositionFile: string;
18
18
  compositionId: string;
19
19
  element: InsertableCompositionElement;
20
20
  from: number | null;
21
- premountFor: number | null;
22
21
  prettierConfigOverride: Record<string, unknown> | null;
23
22
  wrapInSequence?: {
24
23
  dimensions: {
@@ -40,7 +40,7 @@ const resolveCompositionComponent = ({ remotionRoot, compositionFile, compositio
40
40
  environment: makeCodemodEnvironment(remotionRoot, null),
41
41
  });
42
42
  exports.resolveCompositionComponent = resolveCompositionComponent;
43
- const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile, compositionId, element, from, premountFor, prettierConfigOverride, wrapInSequence = null, sourceFileOverrides, }) => {
43
+ const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile, compositionId, element, from, prettierConfigOverride, wrapInSequence = null, sourceFileOverrides, }) => {
44
44
  var _a;
45
45
  var _b, _c;
46
46
  const environment = makeCodemodEnvironment(remotionRoot, sourceFileOverrides);
@@ -61,7 +61,6 @@ const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile,
61
61
  element,
62
62
  environment,
63
63
  from,
64
- premountFor,
65
64
  prettierConfigOverride,
66
65
  wrapInSequence: sequence,
67
66
  });
@@ -69,7 +68,6 @@ const insertJsxElementIntoComposition = async ({ remotionRoot, compositionFile,
69
68
  const codemodElement = createElementFromInsertable({
70
69
  element,
71
70
  from,
72
- premountFor,
73
71
  wrapInSequence: sequence,
74
72
  });
75
73
  const location = await resolveCompositionComponentWithFileCodemod({
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.allApiRoutes = void 0;
4
+ const open_in_app_1 = require("../helpers/open-in-app");
4
5
  const add_composition_1 = require("./routes/add-composition");
5
6
  const add_effect_1 = require("./routes/add-effect");
6
7
  const add_effect_keyframe_1 = require("./routes/add-effect-keyframe");
@@ -8,14 +9,13 @@ const add_folder_1 = require("./routes/add-folder");
8
9
  const add_keyframes_1 = require("./routes/add-keyframes");
9
10
  const add_render_1 = require("./routes/add-render");
10
11
  const add_sequence_keyframe_1 = require("./routes/add-sequence-keyframe");
12
+ const app_info_1 = require("./routes/app-info");
11
13
  const apply_visual_control_change_1 = require("./routes/apply-visual-control-change");
12
14
  const batch_update_keyframe_settings_1 = require("./routes/batch-update-keyframe-settings");
13
15
  const cancel_render_1 = require("./routes/cancel-render");
14
16
  const composition_component_info_1 = require("./routes/composition-component-info");
15
17
  const convert_figma_clipboard_to_svg_1 = require("./routes/convert-figma-clipboard-to-svg");
16
18
  const copy_render_output_to_asset_1 = require("./routes/copy-render-output-to-asset");
17
- const default_coding_agent_1 = require("./routes/default-coding-agent");
18
- const default_editor_1 = require("./routes/default-editor");
19
19
  const delete_composition_1 = require("./routes/delete-composition");
20
20
  const delete_effect_1 = require("./routes/delete-effect");
21
21
  const delete_keyframes_1 = require("./routes/delete-keyframes");
@@ -95,7 +95,7 @@ exports.allApiRoutes = {
95
95
  '/api/open-in-terminal': open_in_terminal_1.openInTerminalHandler,
96
96
  '/api/open-in-git-client': open_in_git_client_1.openInGitClientHandler,
97
97
  '/api/open-in-editor': open_in_editor_1.openInEditorHandler,
98
- '/api/open-in-coding-agent': default_coding_agent_1.openInCodingAgentHandler,
98
+ '/api/open-in-coding-agent': open_in_app_1.openInCodingAgent,
99
99
  '/api/register-client-render': register_client_render_1.registerClientRenderHandler,
100
100
  '/api/unregister-client-render': unregister_client_render_1.unregisterClientRenderHandler,
101
101
  '/api/update-default-props': update_default_props_1.updateDefaultPropsHandler,
@@ -152,8 +152,7 @@ exports.allApiRoutes = {
152
152
  '/api/upgrade-remotion': upgrade_remotion_1.handleUpgradeRemotion,
153
153
  '/api/shutdown-studio': shutdown_studio_1.handleShutdownStudio,
154
154
  '/api/restart-studio': restart_studio_1.handleRestartStudio,
155
- '/api/default-coding-agent-info': default_coding_agent_1.getDefaultCodingAgentInfoHandler,
156
- '/api/default-editor-info': default_editor_1.getDefaultEditorInfoHandler,
155
+ '/api/app-info': app_info_1.appInfoHandler,
157
156
  '/api/insert-composition-element': insert_composition_element_1.insertCompositionElementHandler,
158
157
  '/api/insert-element': insert_element_1.insertElementHandler,
159
158
  '/api/prepare-element-install': prepare_element_install_1.prepareElementInstallHandler,
@@ -7,6 +7,7 @@ export type LiveEventsServer = {
7
7
  closeConnections: () => Promise<void>;
8
8
  addNewClientListener: (cb: () => void) => () => void;
9
9
  };
10
+ export declare const subscribeToConfigChanges: (onChange: () => void) => () => void;
10
11
  export declare const clearPrintPortMessageTimeout: () => void;
11
12
  export type InitialUndoRedoState = {
12
13
  undoFile: string | null;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setLiveEventsListener = exports.getLiveEventsListener = exports.waitForLiveEventsListener = exports.makeLiveEventsRouter = exports.clearPrintPortMessageTimeout = void 0;
3
+ exports.setLiveEventsListener = exports.getLiveEventsListener = exports.waitForLiveEventsListener = exports.makeLiveEventsRouter = exports.clearPrintPortMessageTimeout = exports.subscribeToConfigChanges = void 0;
4
4
  const server_ready_1 = require("../server-ready");
5
5
  const default_props_watchers_1 = require("./default-props-watchers");
6
6
  const file_existence_watchers_1 = require("./file-existence-watchers");
@@ -9,6 +9,14 @@ const serializeMessage = (message) => {
9
9
  return `data: ${JSON.stringify(message)}\n\n`;
10
10
  };
11
11
  let printPortMessageTimeout = null;
12
+ const configChangeListeners = new Set();
13
+ const subscribeToConfigChanges = (onChange) => {
14
+ configChangeListeners.add(onChange);
15
+ return () => {
16
+ configChangeListeners.delete(onChange);
17
+ };
18
+ };
19
+ exports.subscribeToConfigChanges = subscribeToConfigChanges;
12
20
  const clearPrintPortMessageTimeout = () => {
13
21
  if (printPortMessageTimeout) {
14
22
  clearTimeout(printPortMessageTimeout);
@@ -57,6 +65,9 @@ const makeLiveEventsRouter = (logLevel, getInitialUndoRedoState) => {
57
65
  return Promise.resolve();
58
66
  };
59
67
  const sendEventToClient = (event) => {
68
+ if (event.type === 'config-file-changed') {
69
+ configChangeListeners.forEach((listener) => listener());
70
+ }
60
71
  clients.forEach((client) => {
61
72
  client.response.write(serializeMessage(event));
62
73
  });
@@ -0,0 +1,3 @@
1
+ import type { GetAppInfoRequest, GetAppInfoResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const appInfoHandler: ApiHandler<GetAppInfoRequest, GetAppInfoResponse>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.appInfoHandler = void 0;
4
+ const default_coding_agent_1 = require("./default-coding-agent");
5
+ const default_editor_1 = require("./default-editor");
6
+ const appInfoHandler = async (params) => {
7
+ const [editorInfo, codingAgentInfo] = await Promise.all([
8
+ (0, default_editor_1.getDefaultEditorInfoHandler)({ ...params, input: params.input.editor }),
9
+ (0, default_coding_agent_1.getDefaultCodingAgentInfoHandler)({
10
+ ...params,
11
+ input: params.input.codingAgent,
12
+ }),
13
+ ]);
14
+ return { editorInfo, codingAgentInfo };
15
+ };
16
+ exports.appInfoHandler = appInfoHandler;
@@ -1,4 +1,3 @@
1
- import type { GetDefaultCodingAgentInfoRequest, GetDefaultCodingAgentInfoResponse, OpenInCodingAgentRequest, OpenInCodingAgentResponse } from '@remotion/studio-shared';
1
+ import type { GetDefaultCodingAgentInfoRequest, GetDefaultCodingAgentInfoResponse } from '@remotion/studio-shared';
2
2
  import type { ApiHandler } from '../api-types';
3
3
  export declare const getDefaultCodingAgentInfoHandler: ApiHandler<GetDefaultCodingAgentInfoRequest, GetDefaultCodingAgentInfoResponse>;
4
- export declare const openInCodingAgentHandler: ApiHandler<OpenInCodingAgentRequest, OpenInCodingAgentResponse>;
@@ -1,12 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.openInCodingAgentHandler = exports.getDefaultCodingAgentInfoHandler = void 0;
4
- const coding_agent_registry_1 = require("../../helpers/coding-agent-registry");
3
+ exports.getDefaultCodingAgentInfoHandler = void 0;
4
+ const app_discovery_1 = require("../../helpers/app-discovery");
5
5
  const git_client_registry_1 = require("../../helpers/git-client-registry");
6
+ const recently_used_apps_1 = require("../../helpers/recently-used-apps");
6
7
  const terminal_registry_1 = require("../../helpers/terminal-registry");
7
- const getDefaultCodingAgentInfoHandler = async ({ getDefaultCodingAgent }) => {
8
- const installedCodingAgents = await (0, coding_agent_registry_1.getAvailableCodingAgents)();
9
- const runningCodingAgents = await (0, coding_agent_registry_1.getRunningCodingAgents)(installedCodingAgents);
8
+ const getDefaultCodingAgentInfoHandler = async ({ getDefaultCodingAgent, input, remotionRoot }) => {
9
+ await (0, recently_used_apps_1.getRecentlyUsedApps)({
10
+ remotionRoot,
11
+ type: 'coding-agent',
12
+ recentlyUsedIds: input.recentlyUsedIds,
13
+ });
14
+ const { installedCodingAgents, runningCodingAgents } = await (0, app_discovery_1.getAppDiscovery)();
10
15
  const installedTerminals = await (0, terminal_registry_1.getAvailableTerminals)();
11
16
  const installedGitClients = await (0, git_client_registry_1.getAvailableGitClients)();
12
17
  return {
@@ -22,18 +27,3 @@ const getDefaultCodingAgentInfoHandler = async ({ getDefaultCodingAgent }) => {
22
27
  };
23
28
  };
24
29
  exports.getDefaultCodingAgentInfoHandler = getDefaultCodingAgentInfoHandler;
25
- const openInCodingAgentHandler = async ({ input, logLevel, remotionRoot }) => {
26
- const codingAgent = (await (0, coding_agent_registry_1.getAvailableCodingAgents)()).find((agent) => agent.id === input.codingAgentId);
27
- if (!codingAgent) {
28
- return { success: false };
29
- }
30
- return {
31
- success: await (0, coding_agent_registry_1.launchCodingAgent)({
32
- codingAgent,
33
- projectPath: remotionRoot,
34
- logLevel,
35
- prompt: input.prompt,
36
- }),
37
- };
38
- };
39
- exports.openInCodingAgentHandler = openInCodingAgentHandler;
@@ -1,38 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getDefaultEditorInfoHandler = void 0;
4
- const custom_editor_1 = require("../../helpers/custom-editor");
5
- const editor_registry_1 = require("../../helpers/editor-registry");
6
- const getDefaultEditorInfoHandler = async ({ getDefaultEditor }) => {
7
- const installedEditors = await (0, editor_registry_1.getAvailableEditors)();
8
- const runningEditors = await (0, editor_registry_1.getRunningEditors)(installedEditors);
9
- const configuredEditor = getDefaultEditor();
10
- const customEditor = configuredEditor &&
11
- typeof configuredEditor === 'object' &&
12
- (0, custom_editor_1.resolveCustomEditorExecutable)(configuredEditor)
13
- ? configuredEditor
14
- : null;
15
- return {
16
- defaultEditor: configuredEditor && typeof configuredEditor === 'object'
17
- ? 'custom'
18
- : configuredEditor,
19
- runningEditors,
20
- installedEditors: [
21
- ...installedEditors.map(({ id, name, nameWithType }) => ({
22
- id,
23
- name,
24
- nameWithType,
25
- })),
26
- ...(customEditor
27
- ? [
28
- {
29
- id: 'custom',
30
- name: customEditor.name,
31
- nameWithType: customEditor.name,
32
- },
33
- ]
34
- : []),
35
- ],
36
- };
4
+ const app_discovery_1 = require("../../helpers/app-discovery");
5
+ const recently_used_apps_1 = require("../../helpers/recently-used-apps");
6
+ const getDefaultEditorInfoHandler = async ({ getDefaultEditor, input, remotionRoot }) => {
7
+ await (0, recently_used_apps_1.getRecentlyUsedApps)({
8
+ remotionRoot,
9
+ type: 'editor',
10
+ recentlyUsedIds: input.recentlyUsedIds,
11
+ });
12
+ return (0, app_discovery_1.getEditorInfo)(getDefaultEditor());
37
13
  };
38
14
  exports.getDefaultEditorInfoHandler = getDefaultEditorInfoHandler;
@@ -74,6 +74,11 @@ const getExpectedFileState = (existingSource) => {
74
74
  const getElementInstallPlan = async ({ destination, element, installationName, entryPoint, remotionRoot, }) => {
75
75
  var _a;
76
76
  (0, exports.validateElementForInstallation)(element);
77
+ if (destination.type === 'selected-media' &&
78
+ (element.isCaptionStyle !== true ||
79
+ element.installationMode !== 'component-owned-sequence')) {
80
+ throw new Error('The Element must be a component-owned caption style');
81
+ }
77
82
  const componentName = studio_protocol_1.StudioProtocolInternals.getElementComponentNameFromSourceCode(element.sourceCode);
78
83
  if (componentName === null) {
79
84
  throw new Error('Element source must export exactly one named component');
@@ -11,7 +11,7 @@ const sequence_node_path_mutation_1 = require("../sequence-node-path-mutation");
11
11
  const undo_stack_1 = require("../undo-stack");
12
12
  const source_file_write_queue_1 = require("./source-file-write-queue");
13
13
  const { basicCaptionsElementSource, getBasicCaptionsElementFile, insertBasicCaptions, } = codemods_1.CodemodsInternals;
14
- const insertBasicCaptionsHandler = ({ input: { fileName, nodePath, captions, durationInFrames, premountFor }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(() => {
14
+ const insertBasicCaptionsHandler = ({ input: { fileName, nodePath, captions, durationInFrames }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(() => {
15
15
  var _a;
16
16
  try {
17
17
  const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
@@ -45,11 +45,11 @@ const insertBasicCaptionsHandler = ({ input: { fileName, nodePath, captions, dur
45
45
  },
46
46
  });
47
47
  const { output, logLine, nodePathRemappings } = insertBasicCaptions({
48
+ element: null,
48
49
  input: fileContents,
49
50
  nodePath,
50
51
  captions,
51
52
  durationInFrames,
52
- premountFor,
53
53
  importPath: elementFile.importPath,
54
54
  });
55
55
  const nodePathMutation = (0, sequence_node_path_mutation_1.broadcastSequenceNodePathMutation)([{ absolutePath, remappings: nodePathRemappings }], null);
@@ -54,6 +54,16 @@ const validateElement = (element, remotionRoot) => {
54
54
  validateDimension('height', element.height);
55
55
  return;
56
56
  }
57
+ if (element.type === 'text') {
58
+ if (typeof element.text !== 'string' || element.text.trim() === '') {
59
+ throw new Error('Text must be a non-empty string');
60
+ }
61
+ validateDimension('fontSize', element.fontSize);
62
+ if (typeof element.color !== 'string' || element.color.trim() === '') {
63
+ throw new Error('Text color must be a non-empty string');
64
+ }
65
+ return;
66
+ }
57
67
  if (element.type === 'svg') {
58
68
  if (typeof element.markup !== 'string' || element.markup.trim() === '') {
59
69
  throw new Error('SVG markup must be a non-empty string');
@@ -118,6 +128,9 @@ const validateElement = (element, remotionRoot) => {
118
128
  throw new Error('Unsupported element type');
119
129
  };
120
130
  const getElementLabel = (element) => {
131
+ if (element.type === 'text') {
132
+ return '<Interactive.Div>';
133
+ }
121
134
  if (element.type === 'solid') {
122
135
  return '<Solid>';
123
136
  }
@@ -149,17 +162,13 @@ const getElementLabel = (element) => {
149
162
  }
150
163
  throw new Error('Unsupported element type');
151
164
  };
152
- const insertCompositionElementHandler = ({ input: { compositionFile, compositionId, element, from, premountFor }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
165
+ const insertCompositionElementHandler = ({ input: { compositionFile, compositionId, element, from }, remotionRoot, logLevel, }) => (0, source_file_write_queue_1.withSourceFileWriteQueue)(async () => {
153
166
  try {
154
167
  validateElement(element, remotionRoot);
155
168
  if (from !== null &&
156
169
  (!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
157
170
  throw new Error('from must be a non-negative integer');
158
171
  }
159
- if (premountFor !== null &&
160
- (!Number.isInteger(premountFor) || premountFor < 0)) {
161
- throw new Error('premountFor must be a non-negative integer');
162
- }
163
172
  const elementLabel = getElementLabel(element);
164
173
  renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[insert-composition-element] Received request for compositionFile="${compositionFile}" compositionId="${compositionId}" element="${element.type}"`);
165
174
  const { fileName, source, oldContents, output, insertedNodePath, logLine, nodePathRemappings, } = await (0, resolve_composition_component_1.insertJsxElementIntoComposition)({
@@ -168,7 +177,6 @@ const insertCompositionElementHandler = ({ input: { compositionFile, composition
168
177
  compositionId,
169
178
  element,
170
179
  from,
171
- premountFor,
172
180
  prettierConfigOverride: null,
173
181
  sourceFileOverrides: null,
174
182
  });