@remotion/studio-server 4.0.506 → 4.0.508

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 (101) hide show
  1. package/dist/codemods/delete-jsx-node.d.ts +4 -0
  2. package/dist/codemods/delete-jsx-node.js +8 -0
  3. package/dist/codemods/duplicate-jsx-node.d.ts +2 -0
  4. package/dist/codemods/duplicate-jsx-node.js +8 -0
  5. package/dist/codemods/effect-param-expression.js +2 -0
  6. package/dist/codemods/get-node-path-remappings.d.ts +13 -0
  7. package/dist/codemods/get-node-path-remappings.js +87 -0
  8. package/dist/codemods/reorder-sequence.d.ts +2 -1
  9. package/dist/codemods/reorder-sequence.js +8 -0
  10. package/dist/codemods/split-jsx-sequence.d.ts +2 -0
  11. package/dist/codemods/split-jsx-sequence.js +8 -0
  12. package/dist/codemods/update-keyframes/update-keyframes.js +2 -0
  13. package/dist/file-watcher.d.ts +11 -1
  14. package/dist/file-watcher.js +16 -5
  15. package/dist/helpers/coding-agent-registry.d.ts +34 -0
  16. package/dist/helpers/coding-agent-registry.js +442 -21
  17. package/dist/helpers/editor-registry.d.ts +1 -0
  18. package/dist/helpers/editor-registry.js +31 -3
  19. package/dist/helpers/finder-artwork.d.ts +1 -0
  20. package/dist/helpers/finder-artwork.js +4 -0
  21. package/dist/helpers/open-in-editor.js +5 -5
  22. package/dist/helpers/parse-keyframe-easing-expression.js +3 -0
  23. package/dist/helpers/resolve-composition-component.d.ts +2 -1
  24. package/dist/helpers/resolve-composition-component.js +60 -68
  25. package/dist/helpers/resolve-editor.d.ts +2 -0
  26. package/dist/helpers/resolve-editor.js +4 -1
  27. package/dist/helpers/terminal-artwork.d.ts +6 -0
  28. package/dist/helpers/terminal-artwork.js +14 -0
  29. package/dist/helpers/terminal-registry.d.ts +36 -0
  30. package/dist/helpers/terminal-registry.js +401 -0
  31. package/dist/index.d.ts +7 -2
  32. package/dist/preview-server/api-routes.js +7 -4
  33. package/dist/preview-server/handler.d.ts +1 -1
  34. package/dist/preview-server/live-events.d.ts +1 -0
  35. package/dist/preview-server/live-events.js +3 -1
  36. package/dist/preview-server/routes/add-effect-keyframe.js +7 -1
  37. package/dist/preview-server/routes/add-effect.js +7 -1
  38. package/dist/preview-server/routes/add-keyframes.js +10 -2
  39. package/dist/preview-server/routes/add-render.js +2 -0
  40. package/dist/preview-server/routes/add-sequence-keyframe.js +7 -1
  41. package/dist/preview-server/routes/app-icon.d.ts +6 -0
  42. package/dist/preview-server/routes/app-icon.js +66 -0
  43. package/dist/preview-server/routes/apply-codemod.js +15 -2
  44. package/dist/preview-server/routes/apply-visual-control-change.js +7 -1
  45. package/dist/preview-server/routes/batch-update-keyframe-settings.js +10 -2
  46. package/dist/preview-server/routes/can-update-sequence-props.d.ts +1 -0
  47. package/dist/preview-server/routes/can-update-sequence-props.js +33 -9
  48. package/dist/preview-server/routes/copy-render-output-to-asset.d.ts +3 -0
  49. package/dist/preview-server/routes/copy-render-output-to-asset.js +58 -0
  50. package/dist/preview-server/routes/default-coding-agent.d.ts +2 -6
  51. package/dist/preview-server/routes/default-coding-agent.js +19 -88
  52. package/dist/preview-server/routes/default-editor.d.ts +1 -6
  53. package/dist/preview-server/routes/default-editor.js +13 -113
  54. package/dist/preview-server/routes/delete-effect.js +7 -1
  55. package/dist/preview-server/routes/delete-jsx-node.js +16 -2
  56. package/dist/preview-server/routes/delete-keyframes.js +10 -2
  57. package/dist/preview-server/routes/duplicate-effect.js +7 -1
  58. package/dist/preview-server/routes/duplicate-jsx-node.js +17 -5
  59. package/dist/preview-server/routes/insert-element.js +23 -3
  60. package/dist/preview-server/routes/insert-jsx-element.js +17 -2
  61. package/dist/preview-server/routes/move-keyframes.js +10 -2
  62. package/dist/preview-server/routes/open-in-editor.js +1 -1
  63. package/dist/preview-server/routes/open-in-terminal.d.ts +3 -0
  64. package/dist/preview-server/routes/open-in-terminal.js +17 -0
  65. package/dist/preview-server/routes/paste-effects.js +7 -1
  66. package/dist/preview-server/routes/reorder-effect.js +7 -1
  67. package/dist/preview-server/routes/reorder-sequence.js +17 -2
  68. package/dist/preview-server/routes/save-effect-props.js +7 -1
  69. package/dist/preview-server/routes/save-multiple-effect-props.js +10 -2
  70. package/dist/preview-server/routes/save-sequence-props.js +10 -2
  71. package/dist/preview-server/routes/split-jsx-sequence.js +17 -6
  72. package/dist/preview-server/routes/update-config.d.ts +7 -0
  73. package/dist/preview-server/routes/update-config.js +193 -0
  74. package/dist/preview-server/routes/update-default-props.js +7 -1
  75. package/dist/preview-server/routes/update-effect-keyframe-settings.js +7 -1
  76. package/dist/preview-server/routes/update-sequence-keyframe-settings.js +7 -1
  77. package/dist/preview-server/sequence-node-path-mutation.d.ts +7 -0
  78. package/dist/preview-server/sequence-node-path-mutation.js +21 -0
  79. package/dist/preview-server/sequence-props-watchers.js +15 -6
  80. package/dist/preview-server/start-server.d.ts +1 -1
  81. package/dist/preview-server/studio-protocol/handle-discovery.js +3 -4
  82. package/dist/preview-server/studio-protocol/handle-install.js +1 -1
  83. package/dist/preview-server/studio-protocol/handle-license-key.js +2 -2
  84. package/dist/preview-server/studio-protocol/origin-policy.d.ts +2 -5
  85. package/dist/preview-server/studio-protocol/origin-policy.js +6 -30
  86. package/dist/preview-server/undo-stack.d.ts +7 -13
  87. package/dist/preview-server/undo-stack.js +58 -5
  88. package/dist/routes.d.ts +1 -1
  89. package/dist/routes.js +8 -1
  90. package/dist/start-studio.d.ts +1 -1
  91. package/package.json +8 -8
  92. package/web/coding-agent-icons/claude-code.png +0 -0
  93. package/web/coding-agent-icons/codex.png +0 -0
  94. package/web/coding-agent-icons/copilot.png +0 -0
  95. package/web/coding-agent-icons/cursor.png +0 -0
  96. package/dist/preview-server/routes/delete-effect-keyframe.d.ts +0 -3
  97. package/dist/preview-server/routes/delete-effect-keyframe.js +0 -89
  98. package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +0 -3
  99. package/dist/preview-server/routes/delete-sequence-keyframe.js +0 -82
  100. package/dist/preview-server/routes/save-props-mutex.d.ts +0 -1
  101. package/dist/preview-server/routes/save-props-mutex.js +0 -11
@@ -164,7 +164,10 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
164
164
  throw new Error('No keyframes were specified for adding');
165
165
  }
166
166
  (0, undo_stack_1.pushTransactionToUndoStack)({
167
- snapshots,
167
+ snapshots: snapshots.map((snapshot) => ({
168
+ ...snapshot,
169
+ nodePathRemappings: null,
170
+ })),
168
171
  logLevel,
169
172
  remotionRoot,
170
173
  description: getBatchDescription({ totalKeyframes, firstKeyframe }),
@@ -180,7 +183,12 @@ const addKeyframes = async ({ sequenceKeyframes, effectKeyframes, clientId, remo
180
183
  for (const snapshot of snapshots) {
181
184
  (0, undo_stack_1.suppressUndoStackInvalidation)(snapshot.filePath);
182
185
  (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(snapshot.filePath);
183
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(snapshot.filePath, snapshot.newContents, clientId);
186
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
187
+ file: snapshot.filePath,
188
+ content: snapshot.newContents,
189
+ originatorClientId: clientId,
190
+ metadata: null,
191
+ });
184
192
  }
185
193
  for (const log of sequenceLogs) {
186
194
  (0, log_update_1.logUpdate)({
@@ -59,6 +59,7 @@ const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDi
59
59
  offthreadVideoThreads: input.offthreadVideoThreads,
60
60
  mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
61
61
  sampleRate: input.sampleRate,
62
+ licenseKey: input.licenseKey,
62
63
  },
63
64
  logLevel,
64
65
  });
@@ -131,6 +132,7 @@ const handleAddRender = ({ input, entryPoint, remotionRoot, logLevel, binariesDi
131
132
  chromeMode: input.chromeMode,
132
133
  offthreadVideoThreads: input.offthreadVideoThreads,
133
134
  mediaCacheSizeInBytes: input.mediaCacheSizeInBytes,
135
+ licenseKey: input.licenseKey,
134
136
  },
135
137
  entryPoint,
136
138
  remotionRoot,
@@ -54,10 +54,16 @@ const addSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, v
54
54
  },
55
55
  entryType: 'sequence-props',
56
56
  suppressHmrOnFileRestore: true,
57
+ nodePathRemappings: null,
57
58
  });
58
59
  (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
59
60
  (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
60
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
61
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
62
+ file: absolutePath,
63
+ content: output,
64
+ originatorClientId: clientId,
65
+ metadata: null,
66
+ });
61
67
  (0, log_update_1.logUpdate)({
62
68
  fileRelativeToRoot,
63
69
  line: logLine,
@@ -0,0 +1,6 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ export declare const handleAppIcon: ({ request, response, pathname, }: {
3
+ request: IncomingMessage;
4
+ response: ServerResponse<IncomingMessage>;
5
+ pathname: string;
6
+ }) => Promise<void>;
@@ -0,0 +1,66 @@
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.handleAppIcon = void 0;
7
+ const node_buffer_1 = require("node:buffer");
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const renderer_1 = require("@remotion/renderer");
11
+ const finder_artwork_1 = require("../../helpers/finder-artwork");
12
+ const terminal_artwork_1 = require("../../helpers/terminal-artwork");
13
+ const validate_same_origin_1 = require("../validate-same-origin");
14
+ const respondWithNotFound = (response) => {
15
+ response.writeHead(404);
16
+ response.end('App icon not found.');
17
+ };
18
+ const handleAppIcon = ({ request, response, pathname, }) => {
19
+ if (request.method !== 'GET') {
20
+ response.writeHead(405, { Allow: 'GET' });
21
+ response.end('Method not allowed.');
22
+ return Promise.resolve();
23
+ }
24
+ (0, validate_same_origin_1.validateSameOrigin)(request);
25
+ const match = /^\/api\/app-icon\/(coding-agent|file-manager|terminal)\/([a-z0-9-]+)\.png$/.exec(pathname);
26
+ if (!match) {
27
+ respondWithNotFound(response);
28
+ return Promise.resolve();
29
+ }
30
+ const [, kind, id] = match;
31
+ if (kind === 'coding-agent') {
32
+ if (!renderer_1.defaultCodingAgentIds.includes(id)) {
33
+ respondWithNotFound(response);
34
+ return Promise.resolve();
35
+ }
36
+ const filePath = node_path_1.default.join(__dirname, '..', '..', '..', 'web', 'coding-agent-icons', `${id}.png`);
37
+ const stat = (0, node_fs_1.statSync)(filePath);
38
+ response.writeHead(200, {
39
+ 'Cache-Control': 'public, max-age=3600',
40
+ 'Content-Length': stat.size,
41
+ 'Content-Type': 'image/png',
42
+ });
43
+ (0, node_fs_1.createReadStream)(filePath).pipe(response);
44
+ return Promise.resolve();
45
+ }
46
+ const dataUrl = kind === 'file-manager'
47
+ ? id === 'finder'
48
+ ? finder_artwork_1.finderArtworkDataUrl
49
+ : null
50
+ : Object.hasOwn(terminal_artwork_1.terminalArtworkDataUrls, id)
51
+ ? terminal_artwork_1.terminalArtworkDataUrls[id]
52
+ : null;
53
+ if (dataUrl === null) {
54
+ respondWithNotFound(response);
55
+ return Promise.resolve();
56
+ }
57
+ const image = node_buffer_1.Buffer.from(dataUrl.slice(dataUrl.indexOf(',') + 1), 'base64');
58
+ response.writeHead(200, {
59
+ 'Cache-Control': 'public, max-age=3600',
60
+ 'Content-Length': image.length,
61
+ 'Content-Type': 'image/png',
62
+ });
63
+ response.end(image);
64
+ return Promise.resolve();
65
+ };
66
+ exports.handleAppIcon = handleAppIcon;
@@ -190,6 +190,7 @@ const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack }, lo
190
190
  oldContents: input,
191
191
  newContents: null,
192
192
  logLine,
193
+ nodePathRemappings: null,
193
194
  },
194
195
  ];
195
196
  let componentFilePath = null;
@@ -205,6 +206,7 @@ const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack }, lo
205
206
  oldContents: null,
206
207
  newContents: componentFileContents,
207
208
  logLine: 1,
209
+ nodePathRemappings: null,
208
210
  });
209
211
  (0, undo_stack_1.pushTransactionToUndoStack)({
210
212
  snapshots,
@@ -232,15 +234,26 @@ const applyCodemodHandler = ({ input: { codemod, dryRun, symbolicatedStack }, lo
232
234
  },
233
235
  entryType,
234
236
  suppressHmrOnFileRestore: false,
237
+ nodePathRemappings: null,
235
238
  });
236
239
  }
237
240
  (0, undo_stack_1.suppressUndoStackInvalidation)(filePath);
238
241
  if (componentFilePath) {
239
242
  (0, undo_stack_1.suppressUndoStackInvalidation)(componentFilePath);
240
243
  }
241
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(filePath, formatted, undefined);
244
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
245
+ file: filePath,
246
+ content: formatted,
247
+ originatorClientId: undefined,
248
+ metadata: null,
249
+ });
242
250
  if (componentFilePath && componentFileContents !== null) {
243
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(componentFilePath, componentFileContents, undefined);
251
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
252
+ file: componentFilePath,
253
+ content: componentFileContents,
254
+ originatorClientId: undefined,
255
+ metadata: null,
256
+ });
244
257
  }
245
258
  const logMessage = (0, exports.getCodemodLogMessage)(codemod);
246
259
  const editMessage = `${renderer_1.RenderInternals.chalk.blueBright((0, format_log_file_location_1.formatLogFileLocation)({
@@ -123,10 +123,16 @@ const applyVisualControlHandler = ({ input: { fileName, changes }, remotionRoot,
123
123
  },
124
124
  entryType: 'visual-control',
125
125
  suppressHmrOnFileRestore: true,
126
+ nodePathRemappings: null,
126
127
  });
127
128
  (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
128
129
  (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
129
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, undefined);
130
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
131
+ file: absolutePath,
132
+ content: output,
133
+ originatorClientId: undefined,
134
+ metadata: null,
135
+ });
130
136
  (0, live_events_1.waitForLiveEventsListener)().then((listener) => {
131
137
  listener.sendEventToClient({
132
138
  type: 'visual-control-values-changed',
@@ -134,7 +134,10 @@ const batchUpdateKeyframeSettings = async ({ sequenceKeyframes, effectKeyframes,
134
134
  });
135
135
  }
136
136
  (0, undo_stack_1.pushTransactionToUndoStack)({
137
- snapshots,
137
+ snapshots: snapshots.map((snapshot) => ({
138
+ ...snapshot,
139
+ nodePathRemappings: null,
140
+ })),
138
141
  logLevel,
139
142
  remotionRoot,
140
143
  description: totalUpdates === 1
@@ -152,7 +155,12 @@ const batchUpdateKeyframeSettings = async ({ sequenceKeyframes, effectKeyframes,
152
155
  for (const snapshot of snapshots) {
153
156
  (0, undo_stack_1.suppressUndoStackInvalidation)(snapshot.filePath);
154
157
  (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(snapshot.filePath);
155
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(snapshot.filePath, snapshot.newContents, clientId);
158
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)({
159
+ file: snapshot.filePath,
160
+ content: snapshot.newContents,
161
+ originatorClientId: clientId,
162
+ metadata: null,
163
+ });
156
164
  }
157
165
  for (const log of sequenceLogs) {
158
166
  (0, log_update_1.logUpdate)({
@@ -8,6 +8,7 @@ type StaticValueOptions = {
8
8
  export declare const isStaticValue: (node: Expression, options?: StaticValueOptions) => boolean;
9
9
  export declare const extractStaticValue: (node: Expression, options?: StaticValueOptions) => unknown;
10
10
  export declare const getComputedStatus: (node: Expression, ast: File, videoConfigValues: VideoConfigIdentifierValues) => CanUpdateSequencePropStatus;
11
+ export declare const getNodePathForRecastPath: (recastPath: any, ast: File) => SequenceNodePath;
11
12
  export declare const findJsxElementPathAtNodePath: (ast: File, nodePath: SequenceNodePath) => import("ast-types/lib/node-path").NodePath<N, V> | null;
12
13
  export declare const findJsxElementAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXOpeningElement | null;
13
14
  export declare const findJsxElementNodeAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXElement | null;
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.computeSequencePropsStatusFromFilenameByLocation = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.lineColumnToNodePath = exports.findNodePathForJsxElement = exports.getStaticJsxTextContent = exports.hasJsxChildrenAttribute = exports.getStaticJsxChildrenAttribute = exports.findJsxElementNodeAtNodePath = exports.findJsxElementAtNodePath = exports.findJsxElementPathAtNodePath = exports.getComputedStatus = exports.extractStaticValue = exports.isStaticValue = void 0;
36
+ exports.computeSequencePropsStatusFromFilenameByLocation = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.lineColumnToNodePath = exports.findNodePathForJsxElement = exports.getStaticJsxTextContent = exports.hasJsxChildrenAttribute = exports.getStaticJsxChildrenAttribute = exports.findJsxElementNodeAtNodePath = exports.findJsxElementAtNodePath = exports.findJsxElementPathAtNodePath = exports.getNodePathForRecastPath = exports.getComputedStatus = exports.extractStaticValue = exports.isStaticValue = void 0;
37
37
  const node_fs_1 = require("node:fs");
38
38
  const renderer_1 = require("@remotion/renderer");
39
39
  const studio_shared_1 = require("@remotion/studio-shared");
@@ -51,6 +51,10 @@ const video_config_values_1 = require("../../helpers/video-config-values");
51
51
  const jsx_component_identity_1 = require("../jsx-component-identity");
52
52
  const jsx_element_not_found_at_location_error_1 = require("../jsx-element-not-found-at-location-error");
53
53
  const can_update_effect_props_1 = require("./can-update-effect-props");
54
+ // A file write synchronously notifies every sequence subscription. Status
55
+ // computation is read-only, so all subscribers can share one parsed snapshot
56
+ // until the notification burst has finished.
57
+ let cachedSequencePropsStatusAst = null;
54
58
  const staticStatus = (codeValue, numericExpression) => ({
55
59
  status: 'static',
56
60
  codeValue,
@@ -546,6 +550,7 @@ recastPath, ast) => {
546
550
  }
547
551
  return (0, import_agnostic_node_path_1.toImportAgnosticNodePath)({ ast, nodePath: segments });
548
552
  };
553
+ exports.getNodePathForRecastPath = getNodePathForRecastPath;
549
554
  const findJsxElementPathAtNodePath = (ast, nodePath) => {
550
555
  const current = (0, get_ast_node_path_1.getAstNodePath)(ast, nodePath);
551
556
  if (!current) {
@@ -633,7 +638,7 @@ const findNodePathForJsxElement = (ast, target) => {
633
638
  recast.types.visit(ast, {
634
639
  visitJSXOpeningElement(p) {
635
640
  if (p.node === target) {
636
- foundPath = getNodePathForRecastPath(p, ast);
641
+ foundPath = (0, exports.getNodePathForRecastPath)(p, ast);
637
642
  return false;
638
643
  }
639
644
  return this.traverse(p);
@@ -674,7 +679,7 @@ const lineColumnToNodePath = (ast, targetLine, targetColumn, fileContents) => {
674
679
  visitJSXOpeningElement(p) {
675
680
  const { node } = p;
676
681
  if (node.loc && node.loc.start.line === targetLine) {
677
- const nodePath = getNodePathForRecastPath(p, ast);
682
+ const nodePath = (0, exports.getNodePathForRecastPath)(p, ast);
678
683
  lineMatches.push(nodePath);
679
684
  if (node.loc.start.column === recastTargetColumn) {
680
685
  exactMatches.push(nodePath);
@@ -692,7 +697,7 @@ exports.lineColumnToNodePath = lineColumnToNodePath;
692
697
  const PIXEL_VALUE_REGEX = /^-?\d+(\.\d+)?px$/;
693
698
  const isSupportedTranslateValue = (value) => {
694
699
  const parts = value.split(/\s+/);
695
- if (parts.length === 1 || parts.length === 2) {
700
+ if (parts.length >= 1 && parts.length <= 3) {
696
701
  return parts.every((part) => PIXEL_VALUE_REGEX.test(part));
697
702
  }
698
703
  return false;
@@ -921,11 +926,30 @@ const computeSequenceOnlyPropsRecord = ({ jsxElement, jsxElementNode, ast, keys,
921
926
  };
922
927
  const computeSequencePropsStatusFromContent = ({ fileContents, nodePath, componentIdentity, keys, assetKeys = [], effects, videoConfigValues, }) => {
923
928
  var _a;
924
- const ast = (0, parse_ast_1.parseAst)(fileContents);
925
- const videoConfigIdentifierValues = (0, video_config_values_1.getVideoConfigIdentifierValues)({
926
- ast,
927
- videoConfigValues,
928
- });
929
+ if ((cachedSequencePropsStatusAst === null || cachedSequencePropsStatusAst === void 0 ? void 0 : cachedSequencePropsStatusAst.fileContents) !== fileContents) {
930
+ cachedSequencePropsStatusAst = null;
931
+ const snapshot = {
932
+ fileContents,
933
+ ast: (0, parse_ast_1.parseAst)(fileContents),
934
+ videoConfigIdentifierValues: new Map(),
935
+ };
936
+ cachedSequencePropsStatusAst = snapshot;
937
+ queueMicrotask(() => {
938
+ if (cachedSequencePropsStatusAst === snapshot) {
939
+ cachedSequencePropsStatusAst = null;
940
+ }
941
+ });
942
+ }
943
+ const { ast } = cachedSequencePropsStatusAst;
944
+ const videoConfigCacheKey = JSON.stringify(videoConfigValues);
945
+ let videoConfigIdentifierValues = cachedSequencePropsStatusAst.videoConfigIdentifierValues.get(videoConfigCacheKey);
946
+ if (videoConfigIdentifierValues === undefined) {
947
+ videoConfigIdentifierValues = (0, video_config_values_1.getVideoConfigIdentifierValues)({
948
+ ast,
949
+ videoConfigValues,
950
+ });
951
+ cachedSequencePropsStatusAst.videoConfigIdentifierValues.set(videoConfigCacheKey, videoConfigIdentifierValues);
952
+ }
929
953
  const jsxElementNode = (0, exports.findJsxElementNodeAtNodePath)(ast, nodePath);
930
954
  const jsxElement = (_a = jsxElementNode === null || jsxElementNode === void 0 ? void 0 : jsxElementNode.openingElement) !== null && _a !== void 0 ? _a : null;
931
955
  if (!jsxElement || !jsxElementNode) {
@@ -0,0 +1,3 @@
1
+ import type { CopyRenderOutputToAssetRequest, CopyRenderOutputToAssetResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const copyRenderOutputToAssetHandler: ApiHandler<CopyRenderOutputToAssetRequest, CopyRenderOutputToAssetResponse>;
@@ -0,0 +1,58 @@
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.copyRenderOutputToAssetHandler = void 0;
7
+ const node_fs_1 = require("node:fs");
8
+ const promises_1 = require("node:fs/promises");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const resolve_output_path_1 = require("../../helpers/resolve-output-path");
11
+ const copyRenderOutputToAssetHandler = async ({ input: { assetPath, outputPath }, publicDir, remotionRoot }) => {
12
+ if (assetPath.length === 0) {
13
+ throw new Error('Asset path cannot be empty');
14
+ }
15
+ const source = (0, resolve_output_path_1.resolveOutputPath)(remotionRoot, outputPath);
16
+ const destination = node_path_1.default.join(publicDir, assetPath);
17
+ const relativeToPublicDir = node_path_1.default.relative(publicDir, destination);
18
+ if (relativeToPublicDir.startsWith('..') ||
19
+ node_path_1.default.isAbsolute(relativeToPublicDir)) {
20
+ throw new Error(`Not allowed to write to ${relativeToPublicDir}`);
21
+ }
22
+ if (!(0, node_fs_1.existsSync)(source)) {
23
+ throw new Error(`${outputPath} does not exist`);
24
+ }
25
+ const sourceStat = (0, node_fs_1.statSync)(source);
26
+ if (!sourceStat.isFile()) {
27
+ throw new Error(`${outputPath} is not a file`);
28
+ }
29
+ if (source === destination) {
30
+ return { created: false };
31
+ }
32
+ if ((0, node_fs_1.existsSync)(destination)) {
33
+ const destinationStat = (0, node_fs_1.statSync)(destination);
34
+ if (!destinationStat.isFile() || destinationStat.size !== sourceStat.size) {
35
+ throw new Error(`File with name ${assetPath} already exists and is different`);
36
+ }
37
+ return { created: false };
38
+ }
39
+ (0, node_fs_1.mkdirSync)(node_path_1.default.dirname(destination), { recursive: true });
40
+ try {
41
+ await (0, promises_1.copyFile)(source, destination, node_fs_1.constants.COPYFILE_EXCL);
42
+ return { created: true };
43
+ }
44
+ catch (error) {
45
+ if (error instanceof Error &&
46
+ 'code' in error &&
47
+ error.code === 'EEXIST' &&
48
+ (0, node_fs_1.existsSync)(destination)) {
49
+ const destinationStat = (0, node_fs_1.statSync)(destination);
50
+ if (destinationStat.isFile() &&
51
+ destinationStat.size === sourceStat.size) {
52
+ return { created: false };
53
+ }
54
+ }
55
+ throw error;
56
+ }
57
+ };
58
+ exports.copyRenderOutputToAssetHandler = copyRenderOutputToAssetHandler;
@@ -1,8 +1,4 @@
1
- import type { GetDefaultCodingAgentInfoRequest, GetDefaultCodingAgentInfoResponse, UpdateDefaultCodingAgentRequest, UpdateDefaultCodingAgentResponse } from '@remotion/studio-shared';
1
+ import type { GetDefaultCodingAgentInfoRequest, GetDefaultCodingAgentInfoResponse, OpenInCodingAgentRequest, OpenInCodingAgentResponse } from '@remotion/studio-shared';
2
2
  import type { ApiHandler } from '../api-types';
3
- export declare const updateDefaultCodingAgentInConfig: ({ configContents, defaultCodingAgent, }: {
4
- configContents: string;
5
- defaultCodingAgent: "claude-code" | "codex" | "cursor" | "github-copilot" | null;
6
- }) => string;
7
3
  export declare const getDefaultCodingAgentInfoHandler: ApiHandler<GetDefaultCodingAgentInfoRequest, GetDefaultCodingAgentInfoResponse>;
8
- export declare const updateDefaultCodingAgentHandler: ApiHandler<UpdateDefaultCodingAgentRequest, UpdateDefaultCodingAgentResponse>;
4
+ export declare const openInCodingAgentHandler: ApiHandler<OpenInCodingAgentRequest, OpenInCodingAgentResponse>;
@@ -1,103 +1,34 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.updateDefaultCodingAgentHandler = exports.getDefaultCodingAgentInfoHandler = exports.updateDefaultCodingAgentInConfig = void 0;
37
- const node_fs_1 = require("node:fs");
38
- const renderer_1 = require("@remotion/renderer");
39
- const recast = __importStar(require("recast"));
40
- const parse_ast_1 = require("../../codemods/parse-ast");
41
- const file_watcher_1 = require("../../file-watcher");
3
+ exports.openInCodingAgentHandler = exports.getDefaultCodingAgentInfoHandler = void 0;
42
4
  const coding_agent_registry_1 = require("../../helpers/coding-agent-registry");
43
- const updateDefaultCodingAgentInConfig = ({ configContents, defaultCodingAgent, }) => {
44
- const ast = (0, parse_ast_1.parseAst)(configContents);
45
- recast.types.visit(ast.program, {
46
- visitExpressionStatement(path) {
47
- const { expression } = path.node;
48
- if (expression.type === 'CallExpression' &&
49
- expression.callee.type === 'MemberExpression' &&
50
- !expression.callee.computed &&
51
- expression.callee.object.type === 'Identifier' &&
52
- expression.callee.object.name === 'Config' &&
53
- expression.callee.property.type === 'Identifier' &&
54
- expression.callee.property.name === 'setDefaultCodingAgent') {
55
- path.prune();
56
- return false;
57
- }
58
- this.traverse(path);
59
- },
60
- });
61
- const configWithoutExistingCalls = recast.print(ast, {
62
- lineTerminator: '\n',
63
- }).code;
64
- if (defaultCodingAgent === null) {
65
- return configWithoutExistingCalls;
66
- }
67
- const separator = configWithoutExistingCalls.endsWith('\n') ? '' : '\n';
68
- return `${configWithoutExistingCalls}${separator}Config.setDefaultCodingAgent('${defaultCodingAgent}');\n`;
69
- };
70
- exports.updateDefaultCodingAgentInConfig = updateDefaultCodingAgentInConfig;
5
+ const terminal_registry_1 = require("../../helpers/terminal-registry");
71
6
  const getDefaultCodingAgentInfoHandler = async ({ getDefaultCodingAgent }) => {
72
7
  const installedCodingAgents = await (0, coding_agent_registry_1.getAvailableCodingAgents)();
8
+ const installedTerminals = await (0, terminal_registry_1.getAvailableTerminals)();
73
9
  return {
74
10
  defaultCodingAgent: getDefaultCodingAgent(),
75
- installedCodingAgents: installedCodingAgents.map(({ id, name }) => ({
11
+ installedCodingAgents: installedCodingAgents.map(({ id, name, nameWithType }) => ({
76
12
  id,
77
13
  name,
14
+ nameWithType,
78
15
  })),
16
+ installedTerminals: installedTerminals.map(({ id, name }) => ({ id, name })),
79
17
  };
80
18
  };
81
19
  exports.getDefaultCodingAgentInfoHandler = getDefaultCodingAgentInfoHandler;
82
- const updateDefaultCodingAgentHandler = ({ input, configFile }) => {
83
- if (configFile === null || configFile === undefined) {
84
- return Promise.resolve({
85
- success: false,
86
- reason: 'No Remotion config file was loaded.',
87
- });
88
- }
89
- if (input.defaultCodingAgent !== null &&
90
- !renderer_1.defaultCodingAgentIds.includes(input.defaultCodingAgent)) {
91
- return Promise.resolve({
92
- success: false,
93
- reason: `Unknown coding agent: ${input.defaultCodingAgent}`,
94
- });
20
+ const openInCodingAgentHandler = async ({ input, logLevel, remotionRoot }) => {
21
+ const codingAgent = (await (0, coding_agent_registry_1.getAvailableCodingAgents)()).find((agent) => agent.id === input.codingAgentId);
22
+ if (!codingAgent) {
23
+ return { success: false };
95
24
  }
96
- const configContents = (0, node_fs_1.readFileSync)(configFile, 'utf8');
97
- (0, file_watcher_1.writeFileAndNotifyFileWatchers)(configFile, (0, exports.updateDefaultCodingAgentInConfig)({
98
- configContents,
99
- defaultCodingAgent: input.defaultCodingAgent,
100
- }), undefined);
101
- return Promise.resolve({ success: true });
25
+ return {
26
+ success: await (0, coding_agent_registry_1.launchCodingAgent)({
27
+ codingAgent,
28
+ projectPath: remotionRoot,
29
+ logLevel,
30
+ prompt: input.prompt,
31
+ }),
32
+ };
102
33
  };
103
- exports.updateDefaultCodingAgentHandler = updateDefaultCodingAgentHandler;
34
+ exports.openInCodingAgentHandler = openInCodingAgentHandler;
@@ -1,8 +1,3 @@
1
- import type { GetDefaultEditorInfoRequest, GetDefaultEditorInfoResponse, UpdateDefaultEditorRequest, UpdateDefaultEditorResponse } from '@remotion/studio-shared';
1
+ import type { GetDefaultEditorInfoRequest, GetDefaultEditorInfoResponse } from '@remotion/studio-shared';
2
2
  import type { ApiHandler } from '../api-types';
3
- export declare const updateDefaultEditorInConfig: ({ configContents, defaultEditor, }: {
4
- configContents: string;
5
- defaultEditor: "cursor" | "sublime-text" | "vscode" | "vscodium" | "webstorm" | "windsurf" | "zed" | null;
6
- }) => string;
7
3
  export declare const getDefaultEditorInfoHandler: ApiHandler<GetDefaultEditorInfoRequest, GetDefaultEditorInfoResponse>;
8
- export declare const updateDefaultEditorHandler: ApiHandler<UpdateDefaultEditorRequest, UpdateDefaultEditorResponse>;