@remotion/studio-server 4.0.506 → 4.0.507

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 (44) hide show
  1. package/dist/codemods/effect-param-expression.js +2 -0
  2. package/dist/codemods/update-keyframes/update-keyframes.js +2 -0
  3. package/dist/helpers/coding-agent-registry.d.ts +35 -0
  4. package/dist/helpers/coding-agent-registry.js +447 -22
  5. package/dist/helpers/editor-registry.d.ts +1 -0
  6. package/dist/helpers/editor-registry.js +31 -3
  7. package/dist/helpers/open-in-editor.js +5 -5
  8. package/dist/helpers/parse-keyframe-easing-expression.js +3 -0
  9. package/dist/helpers/resolve-editor.d.ts +2 -0
  10. package/dist/helpers/resolve-editor.js +4 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/preview-server/api-routes.js +5 -4
  13. package/dist/preview-server/handler.d.ts +1 -1
  14. package/dist/preview-server/routes/add-render.js +2 -0
  15. package/dist/preview-server/routes/can-update-sequence-props.js +28 -5
  16. package/dist/preview-server/routes/copy-render-output-to-asset.d.ts +3 -0
  17. package/dist/preview-server/routes/copy-render-output-to-asset.js +58 -0
  18. package/dist/preview-server/routes/default-coding-agent.d.ts +2 -6
  19. package/dist/preview-server/routes/default-coding-agent.js +17 -88
  20. package/dist/preview-server/routes/default-editor.d.ts +1 -6
  21. package/dist/preview-server/routes/default-editor.js +13 -113
  22. package/dist/preview-server/routes/open-in-editor.js +1 -1
  23. package/dist/preview-server/routes/update-config.d.ts +7 -0
  24. package/dist/preview-server/routes/update-config.js +188 -0
  25. package/dist/preview-server/start-server.d.ts +1 -1
  26. package/dist/preview-server/studio-protocol/handle-discovery.js +3 -4
  27. package/dist/preview-server/studio-protocol/handle-install.js +1 -1
  28. package/dist/preview-server/studio-protocol/handle-license-key.js +2 -2
  29. package/dist/preview-server/studio-protocol/origin-policy.d.ts +2 -5
  30. package/dist/preview-server/studio-protocol/origin-policy.js +6 -30
  31. package/dist/routes.d.ts +1 -1
  32. package/dist/routes.js +0 -1
  33. package/dist/start-studio.d.ts +1 -1
  34. package/package.json +8 -8
  35. package/web/coding-agent-icons/claude-code.png +0 -0
  36. package/web/coding-agent-icons/codex.png +0 -0
  37. package/web/coding-agent-icons/copilot.png +0 -0
  38. package/web/coding-agent-icons/cursor.png +0 -0
  39. package/dist/preview-server/routes/delete-effect-keyframe.d.ts +0 -3
  40. package/dist/preview-server/routes/delete-effect-keyframe.js +0 -89
  41. package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +0 -3
  42. package/dist/preview-server/routes/delete-sequence-keyframe.js +0 -82
  43. package/dist/preview-server/routes/save-props-mutex.d.ts +0 -1
  44. package/dist/preview-server/routes/save-props-mutex.js +0 -11
@@ -76,6 +76,8 @@ const makeEasingExpression = ({ easing, easingLocalName, }) => {
76
76
  switch (easing.type) {
77
77
  case 'linear':
78
78
  return b.memberExpression(b.identifier(easingLocalName), b.identifier('linear'));
79
+ case 'step1':
80
+ return b.memberExpression(b.identifier(easingLocalName), b.identifier('step1'));
79
81
  case 'spring':
80
82
  return b.callExpression(b.memberExpression(b.identifier(easingLocalName), b.identifier('spring')), [
81
83
  b.objectExpression([
@@ -285,6 +285,8 @@ const createEasingExpression = (easing) => {
285
285
  switch (easing.type) {
286
286
  case 'linear':
287
287
  return b.memberExpression(b.identifier('Easing'), b.identifier('linear'));
288
+ case 'step1':
289
+ return b.memberExpression(b.identifier('Easing'), b.identifier('step1'));
288
290
  case 'spring':
289
291
  return b.callExpression(b.memberExpression(b.identifier('Easing'), b.identifier('spring')), [
290
292
  b.objectExpression([
@@ -2,13 +2,48 @@ import type { DefaultCodingAgent } from '@remotion/renderer';
2
2
  export type InstalledCodingAgent = {
3
3
  id: DefaultCodingAgent;
4
4
  name: string;
5
+ nameWithType: string;
5
6
  applicationPath: string;
7
+ iconDataUrl: string | null;
8
+ platform: SupportedCodingAgentPlatform;
9
+ launchMode: 'direct' | 'terminal';
10
+ terminal: InstalledTerminal | null;
11
+ };
12
+ type SupportedCodingAgentPlatform = 'darwin' | 'linux' | 'win32';
13
+ type LinuxTerminalId = 'x-terminal-emulator' | 'gnome-terminal' | 'konsole' | 'kitty' | 'alacritty' | 'wezterm' | 'xterm';
14
+ type InstalledTerminal = {
15
+ id: LinuxTerminalId | 'cmd';
16
+ path: string;
6
17
  };
7
18
  export type CodingAgentDiscoveryContext = {
8
19
  platform: NodeJS.Platform;
20
+ env: NodeJS.ProcessEnv;
9
21
  homeDirectory: string;
10
22
  pathExists: (filePath: string) => boolean;
11
23
  findMacApplications: (bundleIdentifier: string) => Promise<readonly string[]>;
12
24
  };
13
25
  export declare const discoverAvailableCodingAgents: (context: CodingAgentDiscoveryContext) => Promise<readonly InstalledCodingAgent[]>;
14
26
  export declare const getAvailableCodingAgents: () => Promise<readonly InstalledCodingAgent[]>;
27
+ export declare const getCodingAgentLaunchCommand: ({ codingAgent, projectPath, }: {
28
+ codingAgent: InstalledCodingAgent;
29
+ projectPath: string;
30
+ }) => {
31
+ command: string;
32
+ args: string[];
33
+ cwd: string | null;
34
+ };
35
+ type CodingAgentLaunchCommand = ReturnType<typeof getCodingAgentLaunchCommand> & {
36
+ waitForExit: boolean;
37
+ };
38
+ export declare const getCodingAgentLaunchCommands: ({ codingAgent, projectPath, prompt, }: {
39
+ codingAgent: InstalledCodingAgent;
40
+ projectPath: string;
41
+ prompt: string | null;
42
+ }) => readonly CodingAgentLaunchCommand[];
43
+ export declare const launchCodingAgent: ({ codingAgent, projectPath, logLevel, prompt, }: {
44
+ codingAgent: InstalledCodingAgent;
45
+ projectPath: string;
46
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
47
+ prompt: string | null;
48
+ }) => Promise<boolean>;
49
+ 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.getAvailableCodingAgents = exports.discoverAvailableCodingAgents = void 0;
6
+ exports.launchCodingAgent = exports.getCodingAgentLaunchCommands = exports.getCodingAgentLaunchCommand = exports.getAvailableCodingAgents = exports.discoverAvailableCodingAgents = void 0;
7
7
  const node_child_process_1 = require("node:child_process");
8
8
  const node_fs_1 = require("node:fs");
9
9
  const node_os_1 = require("node:os");
@@ -11,28 +11,165 @@ const node_path_1 = __importDefault(require("node:path"));
11
11
  const node_util_1 = require("node:util");
12
12
  const renderer_1 = require("@remotion/renderer");
13
13
  const execFilePromise = (0, node_util_1.promisify)(node_child_process_1.execFile);
14
+ const getLinuxCommandPaths = (context, command) => [
15
+ node_path_1.default.posix.join('/usr/local/bin', command),
16
+ node_path_1.default.posix.join('/usr/bin', command),
17
+ node_path_1.default.posix.join(context.homeDirectory, '.local/bin', command),
18
+ ];
19
+ const getWindowsCommandPaths = (context, command) => [
20
+ node_path_1.default.win32.join(context.homeDirectory, '.local', 'bin', `${command}.exe`),
21
+ node_path_1.default.win32.join(context.homeDirectory, '.local', 'bin', `${command}.cmd`),
22
+ ];
23
+ const getWindowsEnvironmentPaths = (context, segments) => {
24
+ const paths = [];
25
+ if (context.env.LOCALAPPDATA) {
26
+ paths.push(node_path_1.default.win32.join(context.env.LOCALAPPDATA, 'Programs', ...segments));
27
+ }
28
+ for (const directory of [
29
+ context.env.ProgramFiles,
30
+ context.env['ProgramFiles(x86)'],
31
+ ]) {
32
+ if (directory) {
33
+ paths.push(node_path_1.default.win32.join(directory, ...segments));
34
+ }
35
+ }
36
+ return paths;
37
+ };
14
38
  const codingAgentDefinitions = {
15
39
  codex: {
16
40
  name: 'Codex',
17
- bundleIdentifiers: ['com.openai.codex'],
18
- applicationNames: ['ChatGPT.app'],
41
+ nameWithType: 'Codex',
42
+ darwin: {
43
+ bundleIdentifiers: ['com.openai.codex'],
44
+ applicationNames: ['ChatGPT.app'],
45
+ },
46
+ linux: [
47
+ {
48
+ paths: (context) => getLinuxCommandPaths(context, 'codex'),
49
+ commands: ['codex'],
50
+ launchMode: 'terminal',
51
+ },
52
+ ],
53
+ win32: [
54
+ {
55
+ paths: (context) => [
56
+ ...getWindowsCommandPaths(context, 'codex'),
57
+ ...(context.env.LOCALAPPDATA
58
+ ? [
59
+ node_path_1.default.win32.join(context.env.LOCALAPPDATA, 'OpenAI', 'Codex', 'bin', 'codex.exe'),
60
+ node_path_1.default.win32.join(context.env.LOCALAPPDATA, 'Packages', 'OpenAI.Codex_2p2nqsd0c76g0', 'LocalCache', 'Local', 'OpenAI', 'Codex', 'bin', 'codex.exe'),
61
+ ]
62
+ : []),
63
+ ],
64
+ commands: ['codex.exe', 'codex.cmd'],
65
+ launchMode: 'terminal',
66
+ },
67
+ ],
19
68
  },
20
69
  cursor: {
21
70
  name: 'Cursor',
22
- bundleIdentifiers: ['com.todesktop.230313mzl4w4u92'],
23
- applicationNames: ['Cursor.app'],
71
+ nameWithType: 'Cursor Agent',
72
+ darwin: {
73
+ bundleIdentifiers: ['com.todesktop.230313mzl4w4u92'],
74
+ applicationNames: ['Cursor.app'],
75
+ },
76
+ linux: [
77
+ {
78
+ paths: (context) => getLinuxCommandPaths(context, 'cursor'),
79
+ commands: ['cursor'],
80
+ launchMode: 'direct',
81
+ },
82
+ {
83
+ paths: (context) => [
84
+ ...getLinuxCommandPaths(context, 'cursor-agent'),
85
+ node_path_1.default.posix.join(context.homeDirectory, '.cursor/bin/cursor-agent'),
86
+ ],
87
+ commands: ['cursor-agent'],
88
+ launchMode: 'terminal',
89
+ },
90
+ ],
91
+ win32: [
92
+ {
93
+ paths: (context) => getWindowsEnvironmentPaths(context, ['cursor', 'Cursor.exe']),
94
+ commands: ['Cursor.exe', 'cursor.cmd'],
95
+ launchMode: 'direct',
96
+ },
97
+ {
98
+ paths: (context) => getWindowsCommandPaths(context, 'cursor-agent'),
99
+ commands: ['cursor-agent.exe', 'cursor-agent.cmd'],
100
+ launchMode: 'terminal',
101
+ },
102
+ ],
24
103
  },
25
- 'github-copilot': {
104
+ copilot: {
26
105
  name: 'GitHub Copilot',
27
- bundleIdentifiers: ['com.github.githubapp'],
28
- applicationNames: ['GitHub Copilot.app'],
106
+ nameWithType: 'GitHub Copilot',
107
+ darwin: {
108
+ bundleIdentifiers: ['com.github.githubapp'],
109
+ applicationNames: ['GitHub Copilot.app'],
110
+ },
111
+ linux: [
112
+ {
113
+ paths: (context) => getLinuxCommandPaths(context, 'copilot'),
114
+ commands: ['copilot'],
115
+ launchMode: 'terminal',
116
+ },
117
+ ],
118
+ win32: [
119
+ {
120
+ paths: (context) => getWindowsCommandPaths(context, 'copilot'),
121
+ commands: ['copilot.exe', 'copilot.cmd'],
122
+ launchMode: 'terminal',
123
+ },
124
+ ],
29
125
  },
30
126
  'claude-code': {
31
127
  name: 'Claude Code',
32
- bundleIdentifiers: ['com.anthropic.claudefordesktop'],
33
- applicationNames: ['Claude.app'],
128
+ nameWithType: 'Claude Code',
129
+ darwin: {
130
+ bundleIdentifiers: ['com.anthropic.claudefordesktop'],
131
+ applicationNames: ['Claude.app'],
132
+ },
133
+ linux: [
134
+ {
135
+ paths: (context) => [
136
+ ...getLinuxCommandPaths(context, 'claude'),
137
+ node_path_1.default.posix.join(context.homeDirectory, '.claude/local/claude'),
138
+ ],
139
+ commands: ['claude'],
140
+ launchMode: 'terminal',
141
+ },
142
+ ],
143
+ win32: [
144
+ {
145
+ paths: (context) => getWindowsCommandPaths(context, 'claude'),
146
+ commands: ['claude.exe', 'claude.cmd'],
147
+ launchMode: 'terminal',
148
+ },
149
+ ],
34
150
  },
35
151
  };
152
+ const linuxTerminalDefinitions = [
153
+ {
154
+ id: 'x-terminal-emulator',
155
+ paths: ['/usr/bin/x-terminal-emulator'],
156
+ commands: ['x-terminal-emulator'],
157
+ },
158
+ {
159
+ id: 'gnome-terminal',
160
+ paths: ['/usr/bin/gnome-terminal'],
161
+ commands: ['gnome-terminal'],
162
+ },
163
+ {
164
+ id: 'konsole',
165
+ paths: ['/usr/bin/konsole'],
166
+ commands: ['konsole'],
167
+ },
168
+ { id: 'kitty', paths: ['/usr/bin/kitty'], commands: ['kitty'] },
169
+ { id: 'alacritty', paths: ['/usr/bin/alacritty'], commands: ['alacritty'] },
170
+ { id: 'wezterm', paths: ['/usr/bin/wezterm'], commands: ['wezterm'] },
171
+ { id: 'xterm', paths: ['/usr/bin/xterm'], commands: ['xterm'] },
172
+ ];
36
173
  const findMacApplications = async (bundleIdentifier) => {
37
174
  try {
38
175
  const { stdout } = await execFilePromise('mdfind', [
@@ -47,39 +184,120 @@ const findMacApplications = async (bundleIdentifier) => {
47
184
  return [];
48
185
  }
49
186
  };
187
+ const getBundledCodingAgentIconDataUrl = (id) => `data:image/png;base64,${(0, node_fs_1.readFileSync)(node_path_1.default.join(__dirname, '..', '..', 'web', 'coding-agent-icons', `${id}.png`)).toString('base64')}`;
50
188
  const defaultDiscoveryContext = {
51
189
  platform: process.platform,
190
+ env: process.env,
52
191
  homeDirectory: (0, node_os_1.homedir)(),
53
192
  pathExists: node_fs_1.existsSync,
54
193
  findMacApplications,
55
194
  };
195
+ const getPathDirectories = (context) => {
196
+ var _a, _b;
197
+ const value = (_b = (_a = context.env.PATH) !== null && _a !== void 0 ? _a : context.env.Path) !== null && _b !== void 0 ? _b : '';
198
+ return value.split(context.platform === 'win32' ? ';' : ':').filter(Boolean);
199
+ };
200
+ const findExecutable = ({ paths, commands, context, }) => {
201
+ for (const executablePath of paths) {
202
+ if (context.pathExists(executablePath)) {
203
+ return executablePath;
204
+ }
205
+ }
206
+ const pathImplementation = context.platform === 'win32' ? node_path_1.default.win32 : node_path_1.default.posix;
207
+ for (const directory of getPathDirectories(context)) {
208
+ for (const command of commands) {
209
+ const executablePath = pathImplementation.join(directory, command);
210
+ if (context.pathExists(executablePath)) {
211
+ return executablePath;
212
+ }
213
+ }
214
+ }
215
+ return null;
216
+ };
217
+ const findLinuxTerminal = (context) => {
218
+ for (const definition of linuxTerminalDefinitions) {
219
+ const terminalPath = findExecutable({
220
+ paths: definition.paths,
221
+ commands: definition.commands,
222
+ context,
223
+ });
224
+ if (terminalPath) {
225
+ return { id: definition.id, path: terminalPath };
226
+ }
227
+ }
228
+ return null;
229
+ };
56
230
  const discoverAvailableCodingAgents = async (context) => {
57
- if (context.platform !== 'darwin') {
231
+ var _a, _b;
232
+ if (context.platform !== 'darwin' &&
233
+ context.platform !== 'linux' &&
234
+ context.platform !== 'win32') {
58
235
  return [];
59
236
  }
237
+ const { platform } = context;
238
+ const terminal = platform === 'linux'
239
+ ? findLinuxTerminal(context)
240
+ : platform === 'win32'
241
+ ? {
242
+ id: 'cmd',
243
+ path: (_b = (_a = context.env.ComSpec) !== null && _a !== void 0 ? _a : context.env.COMSPEC) !== null && _b !== void 0 ? _b : 'cmd.exe',
244
+ }
245
+ : null;
60
246
  const installedCodingAgents = [];
61
247
  for (const id of renderer_1.defaultCodingAgentIds) {
62
248
  const definition = codingAgentDefinitions[id];
63
- const discoveredApplications = (await Promise.all(definition.bundleIdentifiers.map((bundleIdentifier) => context.findMacApplications(bundleIdentifier)))).flat();
64
- const knownApplications = definition.applicationNames.flatMap((name) => [
65
- node_path_1.default.posix.join('/Applications', name),
66
- node_path_1.default.posix.join(context.homeDirectory, 'Applications', name),
67
- ]);
68
- for (const applicationPath of new Set([
69
- ...discoveredApplications,
70
- ...knownApplications,
71
- ])) {
72
- if (context.pathExists(applicationPath)) {
249
+ if (platform === 'darwin') {
250
+ const discoveredApplications = (await Promise.all(definition.darwin.bundleIdentifiers.map((bundleIdentifier) => context.findMacApplications(bundleIdentifier)))).flat();
251
+ const knownApplications = definition.darwin.applicationNames.flatMap((name) => [
252
+ node_path_1.default.posix.join('/Applications', name),
253
+ node_path_1.default.posix.join(context.homeDirectory, 'Applications', name),
254
+ ]);
255
+ for (const applicationPath of new Set([
256
+ ...discoveredApplications,
257
+ ...knownApplications,
258
+ ])) {
259
+ if (context.pathExists(applicationPath)) {
260
+ installedCodingAgents.push({
261
+ applicationPath,
262
+ id,
263
+ launchMode: 'direct',
264
+ name: definition.name,
265
+ nameWithType: definition.nameWithType,
266
+ platform,
267
+ terminal: null,
268
+ });
269
+ break;
270
+ }
271
+ }
272
+ continue;
273
+ }
274
+ for (const variant of definition[platform]) {
275
+ if (variant.launchMode === 'terminal' && terminal === null) {
276
+ continue;
277
+ }
278
+ const applicationPath = findExecutable({
279
+ paths: variant.paths(context),
280
+ commands: variant.commands,
281
+ context,
282
+ });
283
+ if (applicationPath) {
73
284
  installedCodingAgents.push({
74
285
  applicationPath,
75
286
  id,
287
+ launchMode: variant.launchMode,
76
288
  name: definition.name,
289
+ nameWithType: definition.nameWithType,
290
+ platform,
291
+ terminal: variant.launchMode === 'terminal' ? terminal : null,
77
292
  });
78
293
  break;
79
294
  }
80
295
  }
81
296
  }
82
- return installedCodingAgents;
297
+ return installedCodingAgents.map((codingAgent) => ({
298
+ ...codingAgent,
299
+ iconDataUrl: getBundledCodingAgentIconDataUrl(codingAgent.id),
300
+ }));
83
301
  };
84
302
  exports.discoverAvailableCodingAgents = discoverAvailableCodingAgents;
85
303
  let availableCodingAgents = null;
@@ -88,3 +306,210 @@ const getAvailableCodingAgents = () => {
88
306
  return availableCodingAgents;
89
307
  };
90
308
  exports.getAvailableCodingAgents = getAvailableCodingAgents;
309
+ const getCodingAgentLaunchCommand = ({ codingAgent, projectPath, }) => {
310
+ if (codingAgent.platform === 'darwin') {
311
+ switch (codingAgent.id) {
312
+ case 'codex':
313
+ return {
314
+ command: node_path_1.default.posix.join(codingAgent.applicationPath, 'Contents/Resources/codex'),
315
+ args: ['app', projectPath],
316
+ cwd: null,
317
+ };
318
+ case 'cursor':
319
+ return {
320
+ command: node_path_1.default.posix.join(codingAgent.applicationPath, 'Contents/Resources/app/bin/cursor'),
321
+ args: ['--glass', '--suppress-popups-on-startup', projectPath],
322
+ cwd: null,
323
+ };
324
+ case 'copilot':
325
+ case 'claude-code':
326
+ return {
327
+ command: 'open',
328
+ args: ['-a', codingAgent.applicationPath, projectPath],
329
+ cwd: null,
330
+ };
331
+ default: {
332
+ const invalidId = codingAgent.id;
333
+ throw new Error(`Unknown coding agent: ${invalidId}`);
334
+ }
335
+ }
336
+ }
337
+ if (codingAgent.launchMode === 'direct') {
338
+ return {
339
+ command: codingAgent.applicationPath,
340
+ args: codingAgent.id === 'cursor'
341
+ ? ['--glass', '--suppress-popups-on-startup', projectPath]
342
+ : [projectPath],
343
+ cwd: null,
344
+ };
345
+ }
346
+ if (codingAgent.terminal === null) {
347
+ throw new Error(`No terminal found for coding agent ${codingAgent.name}`);
348
+ }
349
+ if (codingAgent.terminal.id === 'cmd') {
350
+ return {
351
+ command: codingAgent.terminal.path,
352
+ args: [
353
+ '/d',
354
+ '/s',
355
+ '/c',
356
+ 'start',
357
+ '',
358
+ '/d',
359
+ projectPath,
360
+ codingAgent.terminal.path,
361
+ '/k',
362
+ codingAgent.applicationPath,
363
+ ],
364
+ cwd: null,
365
+ };
366
+ }
367
+ const command = codingAgent.applicationPath;
368
+ switch (codingAgent.terminal.id) {
369
+ case 'gnome-terminal':
370
+ return {
371
+ command: codingAgent.terminal.path,
372
+ args: [`--working-directory=${projectPath}`, '--', command],
373
+ cwd: projectPath,
374
+ };
375
+ case 'konsole':
376
+ return {
377
+ command: codingAgent.terminal.path,
378
+ args: ['--workdir', projectPath, '-e', command],
379
+ cwd: projectPath,
380
+ };
381
+ case 'kitty':
382
+ return {
383
+ command: codingAgent.terminal.path,
384
+ args: ['--directory', projectPath, command],
385
+ cwd: projectPath,
386
+ };
387
+ case 'alacritty':
388
+ return {
389
+ command: codingAgent.terminal.path,
390
+ args: ['--working-directory', projectPath, '-e', command],
391
+ cwd: projectPath,
392
+ };
393
+ case 'wezterm':
394
+ return {
395
+ command: codingAgent.terminal.path,
396
+ args: ['start', '--cwd', projectPath, '--', command],
397
+ cwd: projectPath,
398
+ };
399
+ case 'x-terminal-emulator':
400
+ case 'xterm':
401
+ return {
402
+ command: codingAgent.terminal.path,
403
+ args: ['-e', command],
404
+ cwd: projectPath,
405
+ };
406
+ default: {
407
+ const invalidTerminal = codingAgent.terminal.id;
408
+ throw new Error(`Unknown terminal: ${invalidTerminal}`);
409
+ }
410
+ }
411
+ };
412
+ exports.getCodingAgentLaunchCommand = getCodingAgentLaunchCommand;
413
+ const getCodingAgentLaunchCommands = ({ codingAgent, projectPath, prompt, }) => {
414
+ const defaultCommand = {
415
+ ...(0, exports.getCodingAgentLaunchCommand)({ codingAgent, projectPath }),
416
+ waitForExit: false,
417
+ };
418
+ if (prompt === null ||
419
+ codingAgent.platform !== 'darwin' ||
420
+ codingAgent.id === 'copilot') {
421
+ return [defaultCommand];
422
+ }
423
+ switch (codingAgent.id) {
424
+ case 'codex': {
425
+ const deepLink = new URL('codex://new');
426
+ deepLink.searchParams.set('path', projectPath);
427
+ deepLink.searchParams.set('prompt', prompt);
428
+ return [
429
+ {
430
+ command: 'open',
431
+ args: [deepLink.toString()],
432
+ cwd: null,
433
+ waitForExit: false,
434
+ },
435
+ ];
436
+ }
437
+ case 'cursor': {
438
+ const deepLink = new URL('cursor://anysphere.cursor-deeplink/prompt');
439
+ deepLink.searchParams.set('text', prompt);
440
+ return [
441
+ { ...defaultCommand, waitForExit: true },
442
+ {
443
+ command: 'open',
444
+ args: [deepLink.toString()],
445
+ cwd: null,
446
+ waitForExit: false,
447
+ },
448
+ ];
449
+ }
450
+ case 'claude-code': {
451
+ const deepLink = new URL('claude://code/new');
452
+ deepLink.searchParams.set('folder', projectPath);
453
+ deepLink.searchParams.set('q', prompt);
454
+ return [
455
+ {
456
+ command: 'open',
457
+ args: [deepLink.toString()],
458
+ cwd: null,
459
+ waitForExit: false,
460
+ },
461
+ ];
462
+ }
463
+ default: {
464
+ const invalidId = codingAgent.id;
465
+ throw new Error(`Unknown coding agent: ${invalidId}`);
466
+ }
467
+ }
468
+ };
469
+ exports.getCodingAgentLaunchCommands = getCodingAgentLaunchCommands;
470
+ const launchCodingAgent = async ({ codingAgent, projectPath, logLevel, prompt, }) => {
471
+ const commands = (0, exports.getCodingAgentLaunchCommands)({
472
+ codingAgent,
473
+ projectPath,
474
+ prompt,
475
+ });
476
+ for (const { command, args, cwd, waitForExit } of commands) {
477
+ const success = await new Promise((resolve) => {
478
+ try {
479
+ const child = (0, node_child_process_1.spawn)(command, args, {
480
+ cwd: cwd !== null && cwd !== void 0 ? cwd : undefined,
481
+ detached: !waitForExit,
482
+ shell: false,
483
+ stdio: 'ignore',
484
+ });
485
+ child.once('error', (error) => {
486
+ renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, `Could not launch coding agent ${codingAgent.name}:`, error);
487
+ resolve(false);
488
+ });
489
+ if (waitForExit) {
490
+ child.once('exit', (code) => {
491
+ if (code !== 0) {
492
+ renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, `Could not launch coding agent ${codingAgent.name}: Process exited with code ${code}`);
493
+ }
494
+ resolve(code === 0);
495
+ });
496
+ }
497
+ else {
498
+ child.once('spawn', () => {
499
+ child.unref();
500
+ resolve(true);
501
+ });
502
+ }
503
+ }
504
+ catch (error) {
505
+ renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, `Could not launch coding agent ${codingAgent.name}:`, error);
506
+ resolve(false);
507
+ }
508
+ });
509
+ if (!success) {
510
+ return false;
511
+ }
512
+ }
513
+ return true;
514
+ };
515
+ exports.launchCodingAgent = launchCodingAgent;
@@ -2,6 +2,7 @@ import type { BuiltInEditor } from '@remotion/renderer';
2
2
  export type InstalledEditor = {
3
3
  id: BuiltInEditor;
4
4
  name: string;
5
+ nameWithType: string;
5
6
  process: string;
6
7
  command: string;
7
8
  };