@remotion/studio-server 4.0.532 → 4.0.534
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.
- package/dist/detect-outdated-remotion-skills.d.ts +4 -0
- package/dist/detect-outdated-remotion-skills.js +3 -2
- package/dist/helpers/coding-agent-registry.d.ts +1 -0
- package/dist/helpers/coding-agent-registry.js +30 -6
- package/dist/helpers/editor-registry.d.ts +1 -0
- package/dist/helpers/editor-registry.js +24 -1
- package/dist/helpers/open-in-editor.d.ts +1 -1
- package/dist/helpers/open-in-editor.js +65 -83
- package/dist/helpers/running-processes.d.ts +12 -0
- package/dist/helpers/running-processes.js +88 -0
- package/dist/helpers/video-config-numeric-expression.js +29 -20
- package/dist/helpers/video-config-values.d.ts +6 -3
- package/dist/helpers/video-config-values.js +42 -26
- package/dist/preview-server/api-routes.js +4 -0
- package/dist/preview-server/file-existence-watchers.js +11 -6
- package/dist/preview-server/routes/add-sequence-keyframe.js +0 -1
- package/dist/preview-server/routes/can-update-effect-props.d.ts +4 -6
- package/dist/preview-server/routes/can-update-effect-props.js +5 -28
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +6 -8
- package/dist/preview-server/routes/can-update-sequence-props.js +11 -12
- package/dist/preview-server/routes/default-coding-agent.js +2 -0
- package/dist/preview-server/routes/default-editor.js +5 -1
- package/dist/preview-server/routes/delete-keyframes.d.ts +2 -2
- package/dist/preview-server/routes/delete-keyframes.js +0 -1
- package/dist/preview-server/routes/find-in-file.js +7 -2
- package/dist/preview-server/routes/insert-element.js +17 -7
- package/dist/preview-server/routes/install-remotion-skill.d.ts +2 -1
- package/dist/preview-server/routes/install-remotion-skill.js +87 -56
- package/dist/preview-server/routes/open-in-editor.js +1 -1
- package/dist/preview-server/routes/remotion-skills-info.d.ts +2 -1
- package/dist/preview-server/routes/remotion-skills-info.js +57 -3
- package/dist/preview-server/routes/reorder-sequence.js +6 -3
- package/dist/preview-server/routes/save-sequence-props.js +0 -1
- package/dist/preview-server/routes/shared-memory-capture-support.d.ts +3 -0
- package/dist/preview-server/routes/shared-memory-capture-support.js +13 -0
- package/dist/preview-server/routes/split-sequences.js +2 -1
- package/dist/preview-server/routes/subscribe-to-sequence-props.js +1 -2
- package/dist/preview-server/routes/unsubscribe-from-sequence-props.js +0 -1
- package/dist/preview-server/routes/update-sequence-keyframe-settings.js +0 -1
- package/dist/preview-server/routes/wrap-node.js +13 -4
- package/dist/preview-server/sequence-props-watchers.d.ts +3 -5
- package/dist/preview-server/sequence-props-watchers.js +9 -17
- package/dist/preview-server/update-available.js +17 -0
- package/dist/routes.js +3 -1
- package/dist/start-studio.js +7 -3
- package/package.json +8 -8
|
@@ -15,6 +15,10 @@ export type RemotionSkillsStatus = {
|
|
|
15
15
|
outdatedSkillNames: RemotionSkillName[];
|
|
16
16
|
};
|
|
17
17
|
export declare const parseRemotionSkillVersion: (contents: string) => string | null;
|
|
18
|
+
export declare const readRemotionSkill: (skillFile: string) => {
|
|
19
|
+
installed: boolean;
|
|
20
|
+
version: string | null;
|
|
21
|
+
};
|
|
18
22
|
export declare const getRemotionSkillsDirectories: ({ cwd, homeDirectory, }: {
|
|
19
23
|
cwd: string;
|
|
20
24
|
homeDirectory: string;
|
|
@@ -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.detectOutdatedRemotionSkills = exports.getRemotionSkillsDirectories = exports.parseRemotionSkillVersion = void 0;
|
|
6
|
+
exports.detectOutdatedRemotionSkills = exports.getRemotionSkillsDirectories = exports.readRemotionSkill = exports.parseRemotionSkillVersion = void 0;
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_os_1 = require("node:os");
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -34,10 +34,11 @@ const readRemotionSkill = (skillFile) => {
|
|
|
34
34
|
return { installed: true, version: null };
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
+
exports.readRemotionSkill = readRemotionSkill;
|
|
37
38
|
const getStatusForSkillsDirectory = ({ currentVersion, scope, skillsDirectory, }) => {
|
|
38
39
|
const installedSkills = new Map();
|
|
39
40
|
for (const skillName of remotion_skill_names_1.remotionSkillNames) {
|
|
40
|
-
installedSkills.set(skillName, readRemotionSkill(node_path_1.default.join(skillsDirectory, skillName, 'SKILL.md')));
|
|
41
|
+
installedSkills.set(skillName, (0, exports.readRemotionSkill)(node_path_1.default.join(skillsDirectory, skillName, 'SKILL.md')));
|
|
41
42
|
}
|
|
42
43
|
if ([...installedSkills.values()].every((skill) => !skill.installed)) {
|
|
43
44
|
return { type: 'not-installed', scope, skillsDirectory };
|
|
@@ -23,6 +23,7 @@ export type CodingAgentDiscoveryContext = {
|
|
|
23
23
|
};
|
|
24
24
|
export declare const discoverAvailableCodingAgents: (context: CodingAgentDiscoveryContext) => Promise<readonly InstalledCodingAgent[]>;
|
|
25
25
|
export declare const getAvailableCodingAgents: () => Promise<readonly InstalledCodingAgent[]>;
|
|
26
|
+
export declare const getRunningCodingAgents: (installedCodingAgents: readonly InstalledCodingAgent[]) => Promise<readonly ("claude-code" | "codex" | "copilot" | "cursor")[]>;
|
|
26
27
|
export declare const getCodingAgentLaunchCommand: ({ codingAgent, projectPath, }: {
|
|
27
28
|
codingAgent: InstalledCodingAgent;
|
|
28
29
|
projectPath: string;
|
|
@@ -3,13 +3,14 @@ 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.launchCodingAgent = exports.getCodingAgentLaunchCommands = exports.getCodingAgentLaunchCommand = exports.getAvailableCodingAgents = exports.discoverAvailableCodingAgents = void 0;
|
|
6
|
+
exports.launchCodingAgent = exports.getCodingAgentLaunchCommands = exports.getCodingAgentLaunchCommand = exports.getRunningCodingAgents = 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");
|
|
10
10
|
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
|
+
const running_processes_1 = require("./running-processes");
|
|
13
14
|
const execFilePromise = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
14
15
|
const getLinuxCommandPaths = (context, command) => [
|
|
15
16
|
node_path_1.default.posix.join('/usr/local/bin', command),
|
|
@@ -260,8 +261,8 @@ const discoverAvailableCodingAgents = async (context) => {
|
|
|
260
261
|
applicationPath,
|
|
261
262
|
id,
|
|
262
263
|
launchMode: 'direct',
|
|
263
|
-
name: definition.name,
|
|
264
|
-
nameWithType: definition.nameWithType,
|
|
264
|
+
name: id === 'codex' ? 'ChatGPT' : definition.name,
|
|
265
|
+
nameWithType: id === 'codex' ? 'ChatGPT' : definition.nameWithType,
|
|
265
266
|
platform,
|
|
266
267
|
terminal: null,
|
|
267
268
|
});
|
|
@@ -302,15 +303,38 @@ const getAvailableCodingAgents = () => {
|
|
|
302
303
|
return availableCodingAgents;
|
|
303
304
|
};
|
|
304
305
|
exports.getAvailableCodingAgents = getAvailableCodingAgents;
|
|
306
|
+
const getRunningCodingAgents = async (installedCodingAgents) => {
|
|
307
|
+
if (installedCodingAgents.length === 0) {
|
|
308
|
+
return [];
|
|
309
|
+
}
|
|
310
|
+
const processes = await (0, running_processes_1.getRunningProcesses)();
|
|
311
|
+
if (processes === null) {
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
return installedCodingAgents
|
|
315
|
+
.filter((agent) => (0, running_processes_1.isAppRunning)({
|
|
316
|
+
processes,
|
|
317
|
+
executablePath: agent.applicationPath,
|
|
318
|
+
commands: agent.platform === 'darwin'
|
|
319
|
+
? []
|
|
320
|
+
: codingAgentDefinitions[agent.id][agent.platform].flatMap((variant) => variant.commands),
|
|
321
|
+
platform: agent.platform,
|
|
322
|
+
}))
|
|
323
|
+
.map((agent) => agent.id);
|
|
324
|
+
};
|
|
325
|
+
exports.getRunningCodingAgents = getRunningCodingAgents;
|
|
305
326
|
const getCodingAgentLaunchCommand = ({ codingAgent, projectPath, }) => {
|
|
306
327
|
if (codingAgent.platform === 'darwin') {
|
|
307
328
|
switch (codingAgent.id) {
|
|
308
|
-
case 'codex':
|
|
329
|
+
case 'codex': {
|
|
330
|
+
const deepLink = new URL('codex://new');
|
|
331
|
+
deepLink.searchParams.set('path', projectPath);
|
|
309
332
|
return {
|
|
310
|
-
command:
|
|
311
|
-
args: [
|
|
333
|
+
command: 'open',
|
|
334
|
+
args: [deepLink.toString()],
|
|
312
335
|
cwd: null,
|
|
313
336
|
};
|
|
337
|
+
}
|
|
314
338
|
case 'cursor':
|
|
315
339
|
return {
|
|
316
340
|
command: node_path_1.default.posix.join(codingAgent.applicationPath, 'Contents/Resources/app/bin/cursor'),
|
|
@@ -17,3 +17,4 @@ export type EditorDiscoveryContext = {
|
|
|
17
17
|
export declare const getDefaultEditorName: (id: "cursor" | "sublime-text" | "vscode" | "vscodium" | "webstorm" | "windsurf" | "zed") => string;
|
|
18
18
|
export declare const discoverAvailableEditors: (context: EditorDiscoveryContext) => Promise<readonly InstalledEditor[]>;
|
|
19
19
|
export declare const getAvailableEditors: () => Promise<readonly InstalledEditor[]>;
|
|
20
|
+
export declare const getRunningEditors: (installedEditors: readonly InstalledEditor[]) => Promise<readonly ("cursor" | "sublime-text" | "vscode" | "vscodium" | "webstorm" | "windsurf" | "zed")[]>;
|
|
@@ -3,13 +3,14 @@ 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.getAvailableEditors = exports.discoverAvailableEditors = exports.getDefaultEditorName = void 0;
|
|
6
|
+
exports.getRunningEditors = exports.getAvailableEditors = exports.discoverAvailableEditors = exports.getDefaultEditorName = 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");
|
|
10
10
|
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
|
+
const running_processes_1 = require("./running-processes");
|
|
13
14
|
const execFilePromise = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
14
15
|
const getWindowsEnvironmentPaths = (context, segments) => {
|
|
15
16
|
const paths = [];
|
|
@@ -526,3 +527,25 @@ const getAvailableEditors = () => {
|
|
|
526
527
|
return availableEditors;
|
|
527
528
|
};
|
|
528
529
|
exports.getAvailableEditors = getAvailableEditors;
|
|
530
|
+
const getRunningEditors = async (installedEditors) => {
|
|
531
|
+
const { platform } = process;
|
|
532
|
+
if (installedEditors.length === 0 ||
|
|
533
|
+
(platform !== 'darwin' && platform !== 'linux' && platform !== 'win32')) {
|
|
534
|
+
return [];
|
|
535
|
+
}
|
|
536
|
+
const processes = await (0, running_processes_1.getRunningProcesses)();
|
|
537
|
+
if (processes === null) {
|
|
538
|
+
return [];
|
|
539
|
+
}
|
|
540
|
+
return installedEditors
|
|
541
|
+
.filter((editor) => (0, running_processes_1.isAppRunning)({
|
|
542
|
+
processes,
|
|
543
|
+
executablePath: editor.process,
|
|
544
|
+
commands: editorDefinitions[editor.id][platform]
|
|
545
|
+
.map((variant) => 'commands' in variant ? variant.commands : [variant.command])
|
|
546
|
+
.flat(),
|
|
547
|
+
platform,
|
|
548
|
+
}))
|
|
549
|
+
.map(({ id }) => id);
|
|
550
|
+
};
|
|
551
|
+
exports.getRunningEditors = getRunningEditors;
|
|
@@ -1,38 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Duplicated in create-video/src/open-in-editor.ts
|
|
3
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
-
if (k2 === undefined) k2 = k;
|
|
5
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
-
}
|
|
9
|
-
Object.defineProperty(o, k2, desc);
|
|
10
|
-
}) : (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
o[k2] = m[k];
|
|
13
|
-
}));
|
|
14
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
-
}) : function(o, v) {
|
|
17
|
-
o["default"] = v;
|
|
18
|
-
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
-
var ownKeys = function(o) {
|
|
21
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
-
var ar = [];
|
|
23
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
-
return ar;
|
|
25
|
-
};
|
|
26
|
-
return ownKeys(o);
|
|
27
|
-
};
|
|
28
|
-
return function (mod) {
|
|
29
|
-
if (mod && mod.__esModule) return mod;
|
|
30
|
-
var result = {};
|
|
31
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
-
__setModuleDefault(result, mod);
|
|
33
|
-
return result;
|
|
34
|
-
};
|
|
35
|
-
})();
|
|
36
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
5
|
};
|
|
@@ -40,27 +7,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
7
|
exports.findMacOsEditorsFromProcessOutput = exports.getDisplayNameForEditor = void 0;
|
|
41
8
|
exports.guessEditor = guessEditor;
|
|
42
9
|
exports.launchEditor = launchEditor;
|
|
43
|
-
const node_child_process_1 =
|
|
10
|
+
const node_child_process_1 = __importDefault(require("node:child_process"));
|
|
44
11
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
45
12
|
const node_os_1 = __importDefault(require("node:os"));
|
|
46
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
47
|
-
const node_util_1 = __importDefault(require("node:util"));
|
|
48
14
|
const renderer_1 = require("@remotion/renderer");
|
|
49
15
|
const open_in_editor_url_scheme_1 = require("./open-in-editor-url-scheme");
|
|
16
|
+
const running_processes_1 = require("./running-processes");
|
|
50
17
|
const { Log } = renderer_1.RenderInternals;
|
|
51
|
-
const execProm = node_util_1.default.promisify(node_child_process_1.exec);
|
|
52
18
|
const isVsCodeDerivative = (editor) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
19
|
+
const editorBasename = node_path_1.default.basename(editor).replace(/\.(exe|cmd|bat)$/i, '');
|
|
20
|
+
return [
|
|
21
|
+
'code',
|
|
22
|
+
'Code',
|
|
23
|
+
'code-insiders',
|
|
24
|
+
'Code - Insiders',
|
|
25
|
+
'vscodium',
|
|
26
|
+
'VSCodium',
|
|
27
|
+
'codium',
|
|
28
|
+
'com.vscodium.codium',
|
|
29
|
+
'com.visualstudio.code',
|
|
30
|
+
'com.visualstudio.code.insiders',
|
|
31
|
+
'cursor',
|
|
32
|
+
'Cursor',
|
|
33
|
+
'windsurf',
|
|
34
|
+
'Windsurf',
|
|
35
|
+
].includes(editorBasename);
|
|
64
36
|
};
|
|
65
37
|
function isTerminalEditor(editor) {
|
|
66
38
|
switch (editor) {
|
|
@@ -257,6 +229,11 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, colNumber) {
|
|
|
257
229
|
if (isZedEditor) {
|
|
258
230
|
return ['--existing', fileName + ':' + lineNumber + ':' + colNumber];
|
|
259
231
|
}
|
|
232
|
+
if (isVsCodeDerivative(editor)) {
|
|
233
|
+
return isFolder
|
|
234
|
+
? [fileName]
|
|
235
|
+
: ['-g', fileName + ':' + lineNumber + ':' + colNumber];
|
|
236
|
+
}
|
|
260
237
|
switch (editorBasename) {
|
|
261
238
|
case 'atom':
|
|
262
239
|
case 'Atom':
|
|
@@ -284,21 +261,6 @@ function getArgumentsForLineNumber(editor, fileName, lineNumber, colNumber) {
|
|
|
284
261
|
case 'mate':
|
|
285
262
|
case 'mine':
|
|
286
263
|
return ['--line', lineNumber, fileName];
|
|
287
|
-
case 'code':
|
|
288
|
-
case 'Code':
|
|
289
|
-
case 'code-insiders':
|
|
290
|
-
case 'Code - Insiders':
|
|
291
|
-
case 'vscodium':
|
|
292
|
-
case 'VSCodium':
|
|
293
|
-
case 'codium':
|
|
294
|
-
case 'com.vscodium.codium':
|
|
295
|
-
case 'com.visualstudio.code':
|
|
296
|
-
case 'com.visualstudio.code.insiders':
|
|
297
|
-
case 'cursor':
|
|
298
|
-
case 'Cursor':
|
|
299
|
-
case 'windsurf':
|
|
300
|
-
case 'Windsurf':
|
|
301
|
-
return ['-g', fileName + ':' + lineNumber + ':' + colNumber];
|
|
302
264
|
case 'appcode':
|
|
303
265
|
case 'clion':
|
|
304
266
|
case 'clion64':
|
|
@@ -340,22 +302,20 @@ const findMacOsEditorsFromProcessOutput = (output) => {
|
|
|
340
302
|
};
|
|
341
303
|
exports.findMacOsEditorsFromProcessOutput = findMacOsEditorsFromProcessOutput;
|
|
342
304
|
async function guessEditor() {
|
|
343
|
-
// We can find out which editor is currently running by:
|
|
344
|
-
// `ps x` on macOS and Linux
|
|
345
|
-
// `Get-Process` on Windows
|
|
346
305
|
const availableEditors = [];
|
|
347
|
-
|
|
306
|
+
const processes = await (0, running_processes_1.getRunningProcesses)();
|
|
307
|
+
if (processes !== null) {
|
|
348
308
|
if (process.platform === 'darwin') {
|
|
349
|
-
const output =
|
|
309
|
+
const output = processes
|
|
310
|
+
.map(({ executable }) => executable !== null && executable !== void 0 ? executable : '')
|
|
311
|
+
.join('\n');
|
|
350
312
|
return (0, exports.findMacOsEditorsFromProcessOutput)(output);
|
|
351
313
|
}
|
|
352
314
|
if (process.platform === 'win32') {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
for (let i = 0; i < runningProcesses.length; i++) {
|
|
358
|
-
const processPath = runningProcesses[i].trim();
|
|
315
|
+
for (const { executable: processPath } of processes) {
|
|
316
|
+
if (processPath === null) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
359
319
|
const processName = node_path_1.default.basename(processPath);
|
|
360
320
|
if (COMMON_EDITORS_WIN.indexOf(processName) !== -1) {
|
|
361
321
|
availableEditors.push({
|
|
@@ -367,10 +327,9 @@ async function guessEditor() {
|
|
|
367
327
|
return availableEditors;
|
|
368
328
|
}
|
|
369
329
|
if (process.platform === 'linux') {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
const output = (await execProm('ps x --no-heading -o comm --sort=comm')).stdout.toString();
|
|
330
|
+
const output = processes
|
|
331
|
+
.map(({ executable }) => executable !== null && executable !== void 0 ? executable : '')
|
|
332
|
+
.join('\n');
|
|
374
333
|
const processNames = Object.keys(COMMON_EDITORS_LINUX);
|
|
375
334
|
for (let i = 0; i < processNames.length; i++) {
|
|
376
335
|
const processName = processNames[i];
|
|
@@ -384,9 +343,6 @@ async function guessEditor() {
|
|
|
384
343
|
return availableEditors;
|
|
385
344
|
}
|
|
386
345
|
}
|
|
387
|
-
catch (_a) {
|
|
388
|
-
// Ignore...
|
|
389
|
-
}
|
|
390
346
|
// Last resort, use old skool env vars
|
|
391
347
|
if (process.env.VISUAL) {
|
|
392
348
|
return [
|
|
@@ -407,7 +363,8 @@ async function guessEditor() {
|
|
|
407
363
|
return [];
|
|
408
364
|
}
|
|
409
365
|
let _childProcess = null;
|
|
410
|
-
async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNewWindow, logLevel, }) {
|
|
366
|
+
async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNewWindow, logLevel, }, projectFolder = null) {
|
|
367
|
+
var _a;
|
|
411
368
|
if (!node_fs_1.default.existsSync(fileName)) {
|
|
412
369
|
return false;
|
|
413
370
|
}
|
|
@@ -425,6 +382,9 @@ async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNew
|
|
|
425
382
|
if (editor.command.toLowerCase() === 'none') {
|
|
426
383
|
return false;
|
|
427
384
|
}
|
|
385
|
+
let folderToOpen = isVsCodeDerivative(editor.command) && !node_fs_1.default.statSync(fileName).isDirectory()
|
|
386
|
+
? projectFolder
|
|
387
|
+
: null;
|
|
428
388
|
if (process.platform === 'linux' &&
|
|
429
389
|
fileName.startsWith('/mnt/') &&
|
|
430
390
|
/Microsoft/i.test(node_os_1.default.release())) {
|
|
@@ -435,13 +395,16 @@ async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNew
|
|
|
435
395
|
// When a Windows editor is specified, interop functionality can
|
|
436
396
|
// handle the path translation, but only if a relative path is used.
|
|
437
397
|
fileName = node_path_1.default.relative('', fileName);
|
|
398
|
+
if (folderToOpen !== null) {
|
|
399
|
+
folderToOpen = node_path_1.default.relative('', folderToOpen);
|
|
400
|
+
}
|
|
438
401
|
}
|
|
439
402
|
// cmd.exe on Windows is vulnerable to RCE attacks given a file name of the
|
|
440
403
|
// form "C:\Users\myusername\Downloads\& curl 172.21.93.52". Use a whitelist
|
|
441
404
|
// to validate user-provided file names. This doesn't cover the entire range
|
|
442
405
|
// of valid file names but should cover almost all of them in practice.
|
|
443
406
|
if (process.platform === 'win32' &&
|
|
444
|
-
!WINDOWS_FILE_NAME_WHITELIST.test(
|
|
407
|
+
[fileName, folderToOpen].some((target) => target !== null && !WINDOWS_FILE_NAME_WHITELIST.test(target.trim()))) {
|
|
445
408
|
Log.error({ indent: false, logLevel });
|
|
446
409
|
Log.error({ indent: false, logLevel }, 'Could not open ' + node_path_1.default.basename(fileName) + ' in the editor.');
|
|
447
410
|
Log.error({ indent: false, logLevel });
|
|
@@ -453,7 +416,8 @@ async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNew
|
|
|
453
416
|
return false;
|
|
454
417
|
}
|
|
455
418
|
const shouldOpenVsCodeNewWindow = isVsCodeDerivative(editor.command) && vsCodeNewWindow;
|
|
456
|
-
|
|
419
|
+
// The file URL cannot specify both a workspace folder and a source location.
|
|
420
|
+
if (!shouldOpenVsCodeNewWindow && folderToOpen === null) {
|
|
457
421
|
const result = (0, open_in_editor_url_scheme_1.openInEditorViaUrlScheme)({
|
|
458
422
|
editor: editor.command,
|
|
459
423
|
fileName,
|
|
@@ -472,6 +436,24 @@ async function launchEditor({ colNumber, editor, fileName, lineNumber, vsCodeNew
|
|
|
472
436
|
: lineNumber
|
|
473
437
|
? getArgumentsForLineNumber(editor.command, fileName, String(lineNumber), colNumber)
|
|
474
438
|
: [fileName];
|
|
439
|
+
if (folderToOpen !== null) {
|
|
440
|
+
args.unshift(folderToOpen);
|
|
441
|
+
}
|
|
442
|
+
if (process.platform === 'darwin' && folderToOpen !== null) {
|
|
443
|
+
const applicationPath = (_a = editor.process.match(/^(.*?\.app)\/Contents\//)) === null || _a === void 0 ? void 0 : _a[1];
|
|
444
|
+
if (applicationPath && node_fs_1.default.existsSync(applicationPath)) {
|
|
445
|
+
// Match the CLI's native macOS launch without starting its Node.js wrapper.
|
|
446
|
+
// -n lets Electron receive the arguments and forward them to a running instance.
|
|
447
|
+
const opened = await new Promise((resolve) => {
|
|
448
|
+
const proc = node_child_process_1.default.spawn('open', ['-n', '-g', '-a', applicationPath, '--args', ...args], { stdio: 'ignore' });
|
|
449
|
+
proc.on('error', () => resolve(false));
|
|
450
|
+
proc.on('close', (code) => resolve(code === 0));
|
|
451
|
+
});
|
|
452
|
+
if (opened) {
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
475
457
|
if (_childProcess && isTerminalEditor(editor.command)) {
|
|
476
458
|
// There's an existing editor process already and it's attached
|
|
477
459
|
// to the terminal, so go kill it. Otherwise two separate editor
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type RunningProcess = {
|
|
2
|
+
executable: string | null;
|
|
3
|
+
commandLine: string | null;
|
|
4
|
+
};
|
|
5
|
+
export declare const isAppRunning: ({ processes, executablePath, commands, platform, }: {
|
|
6
|
+
processes: readonly RunningProcess[];
|
|
7
|
+
executablePath: string;
|
|
8
|
+
commands: readonly string[];
|
|
9
|
+
platform: NodeJS.Platform;
|
|
10
|
+
}) => boolean;
|
|
11
|
+
export declare const getRunningProcesses: () => Promise<readonly RunningProcess[] | null>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRunningProcesses = exports.isAppRunning = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_util_1 = require("node:util");
|
|
6
|
+
const execFilePromise = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
7
|
+
let processSnapshot = null;
|
|
8
|
+
const isAppRunning = ({ processes, executablePath, commands, platform, }) => {
|
|
9
|
+
if (platform === 'darwin') {
|
|
10
|
+
const applicationPath = executablePath.split('/Contents/')[0];
|
|
11
|
+
if (applicationPath.endsWith('.app')) {
|
|
12
|
+
return processes.some(({ executable }) => executable === null || executable === void 0 ? void 0 : executable.startsWith(`${applicationPath}/Contents/MacOS/`));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const escapedCommands = commands.map((command) => command.replace(/\.(exe|cmd)$/i, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
16
|
+
const escapedPath = executablePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
17
|
+
const executablePattern = new RegExp(`^"?(?:${escapedPath}|(?:[^"\\s]*[/\\\\])?(?:${escapedCommands.join('|')})(?:\\.(?:exe|cmd|js))?)"?(?=\\s|$)`, platform === 'win32' ? 'i' : '');
|
|
18
|
+
return processes.some(({ executable, commandLine }) => {
|
|
19
|
+
// Windows terminal launches put the app after the command interpreter.
|
|
20
|
+
const withoutCmd = (commandLine !== null && commandLine !== void 0 ? commandLine : '').replace(/^(?:"[^"\r\n]*[/\\]cmd(?:\.exe)?"|(?:[^\s"]*[/\\])?cmd(?:\.exe)?)\s+\/[ck]\s+/i, '');
|
|
21
|
+
// Node-based CLIs put the script after the interpreter path.
|
|
22
|
+
const withoutNode = withoutCmd.replace(/^(?:"[^"\r\n]*[/\\]node(?:\.exe)?"|(?:[^\s"]*[/\\])?node(?:\.exe)?)\s+/i, '');
|
|
23
|
+
return (executablePattern.test(executable !== null && executable !== void 0 ? executable : '') ||
|
|
24
|
+
executablePattern.test(withoutNode));
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
exports.isAppRunning = isAppRunning;
|
|
28
|
+
const getRunningProcesses = () => {
|
|
29
|
+
if (processSnapshot !== null && processSnapshot.expiresAt > Date.now()) {
|
|
30
|
+
return processSnapshot.promise;
|
|
31
|
+
}
|
|
32
|
+
const snapshot = {
|
|
33
|
+
expiresAt: Infinity,
|
|
34
|
+
promise: (async () => {
|
|
35
|
+
try {
|
|
36
|
+
if (process.platform === 'win32') {
|
|
37
|
+
const { stdout } = await execFilePromise('powershell.exe', [
|
|
38
|
+
'-NoProfile',
|
|
39
|
+
'-NonInteractive',
|
|
40
|
+
'-Command',
|
|
41
|
+
'ConvertTo-Json -Compress -InputObject @(Get-CimInstance Win32_Process | Select-Object ExecutablePath, CommandLine)',
|
|
42
|
+
], { timeout: 5000 });
|
|
43
|
+
const processes = JSON.parse(stdout);
|
|
44
|
+
return processes.map(({ ExecutablePath, CommandLine }) => ({
|
|
45
|
+
executable: ExecutablePath,
|
|
46
|
+
commandLine: CommandLine,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
if (process.platform === 'darwin') {
|
|
50
|
+
const { stdout } = await execFilePromise('ps', ['-ax', '-o', 'comm='], {
|
|
51
|
+
timeout: 5000,
|
|
52
|
+
});
|
|
53
|
+
return stdout
|
|
54
|
+
.split('\n')
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.map((line) => ({
|
|
57
|
+
executable: line.trim(),
|
|
58
|
+
commandLine: null,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
if (process.platform === 'linux') {
|
|
62
|
+
// Use a fixed-width name column to preserve spaces in both fields.
|
|
63
|
+
const executableWidth = 64;
|
|
64
|
+
const { stdout } = await execFilePromise('ps', ['-e', '-ww', '-o', `comm:${executableWidth}=`, '-o', 'args='], { timeout: 5000 });
|
|
65
|
+
return stdout
|
|
66
|
+
.split('\n')
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
.map((line) => ({
|
|
69
|
+
executable: line.slice(0, executableWidth).trim(),
|
|
70
|
+
commandLine: line.slice(executableWidth).trim(),
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch (_a) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
})(),
|
|
79
|
+
};
|
|
80
|
+
processSnapshot = snapshot;
|
|
81
|
+
// Share the in-flight query and its result across nearby editor and agent
|
|
82
|
+
// requests, but refresh it when Studio is revisited later.
|
|
83
|
+
snapshot.promise.then(() => {
|
|
84
|
+
snapshot.expiresAt = Date.now() + 1000;
|
|
85
|
+
});
|
|
86
|
+
return snapshot.promise;
|
|
87
|
+
};
|
|
88
|
+
exports.getRunningProcesses = getRunningProcesses;
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.updateVideoConfigNumericExpression = exports.parseVideoConfigNumericExpression = void 0;
|
|
37
37
|
const recast = __importStar(require("recast"));
|
|
38
|
+
const no_react_1 = require("remotion/no-react");
|
|
38
39
|
const b = recast.types.builders;
|
|
39
40
|
const getNumericLiteral = (node) => {
|
|
40
41
|
if (node.type === 'NumericLiteral') {
|
|
@@ -61,11 +62,13 @@ const getVideoConfigValue = ({ node, videoConfigValues, }) => {
|
|
|
61
62
|
if (node.type !== 'Identifier') {
|
|
62
63
|
return null;
|
|
63
64
|
}
|
|
64
|
-
const
|
|
65
|
-
|
|
65
|
+
const binding = videoConfigValues instanceof Map
|
|
66
|
+
? videoConfigValues.get(node)
|
|
67
|
+
: videoConfigValues[node.name];
|
|
68
|
+
if (binding === undefined) {
|
|
66
69
|
return null;
|
|
67
70
|
}
|
|
68
|
-
return { identifier: node.name,
|
|
71
|
+
return { identifier: node.name, binding };
|
|
69
72
|
};
|
|
70
73
|
const parseVideoConfigNumericExpression = ({ node, videoConfigValues, }) => {
|
|
71
74
|
if (node.type === 'TSAsExpression') {
|
|
@@ -96,16 +99,11 @@ const parseVideoConfigNumericExpression = ({ node, videoConfigValues, }) => {
|
|
|
96
99
|
if (minuend === null || subtrahend === null) {
|
|
97
100
|
return null;
|
|
98
101
|
}
|
|
99
|
-
const resolvedValue = minuend.value - subtrahend;
|
|
100
|
-
if (!Number.isFinite(resolvedValue)) {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
102
|
return {
|
|
104
103
|
type: 'video-config-subtraction',
|
|
105
104
|
identifier: minuend.identifier,
|
|
106
|
-
|
|
105
|
+
binding: minuend.binding,
|
|
107
106
|
subtrahend,
|
|
108
|
-
value: resolvedValue,
|
|
109
107
|
};
|
|
110
108
|
}
|
|
111
109
|
if (node.operator !== '*') {
|
|
@@ -131,17 +129,12 @@ const parseVideoConfigNumericExpression = ({ node, videoConfigValues, }) => {
|
|
|
131
129
|
}
|
|
132
130
|
const multiplier = factorPosition === 'left' ? leftNumber : rightNumber;
|
|
133
131
|
const configValue = factorPosition === 'left' ? rightVideoConfig : leftVideoConfig;
|
|
134
|
-
const value = multiplier * configValue.value;
|
|
135
|
-
if (!Number.isFinite(value)) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
132
|
return {
|
|
139
133
|
type: 'video-config-multiplication',
|
|
140
134
|
identifier: configValue.identifier,
|
|
141
135
|
multiplier,
|
|
142
|
-
|
|
136
|
+
binding: configValue.binding,
|
|
143
137
|
factorPosition,
|
|
144
|
-
value,
|
|
145
138
|
};
|
|
146
139
|
};
|
|
147
140
|
exports.parseVideoConfigNumericExpression = parseVideoConfigNumericExpression;
|
|
@@ -156,13 +149,21 @@ const updateVideoConfigNumericExpression = ({ expression, value, }) => {
|
|
|
156
149
|
return numericExpression(value);
|
|
157
150
|
}
|
|
158
151
|
if (expression.type === 'video-config-value') {
|
|
159
|
-
return value ===
|
|
152
|
+
return value ===
|
|
153
|
+
no_react_1.NoReactInternals.evaluateSourceNumericValue(expression, null)
|
|
160
154
|
? b.identifier(expression.identifier)
|
|
161
155
|
: numericExpression(value);
|
|
162
156
|
}
|
|
163
157
|
if (expression.type === 'video-config-subtraction') {
|
|
164
|
-
const subtrahend = expression.
|
|
165
|
-
|
|
158
|
+
const subtrahend = (expression.binding.type === 'constant'
|
|
159
|
+
? expression.binding.value
|
|
160
|
+
: NaN) - value;
|
|
161
|
+
if (!Number.isFinite(subtrahend) ||
|
|
162
|
+
(expression.binding.type === 'constant'
|
|
163
|
+
? expression.binding.value
|
|
164
|
+
: NaN) -
|
|
165
|
+
subtrahend !==
|
|
166
|
+
value) {
|
|
166
167
|
return numericExpression(value);
|
|
167
168
|
}
|
|
168
169
|
return b.binaryExpression('-', b.identifier(expression.identifier), numericExpression(subtrahend));
|
|
@@ -170,8 +171,16 @@ const updateVideoConfigNumericExpression = ({ expression, value, }) => {
|
|
|
170
171
|
if (expression.type !== 'video-config-multiplication' || value === 0) {
|
|
171
172
|
return numericExpression(value);
|
|
172
173
|
}
|
|
173
|
-
const multiplier = value /
|
|
174
|
-
|
|
174
|
+
const multiplier = value /
|
|
175
|
+
(expression.binding.type === 'constant' ? expression.binding.value : NaN);
|
|
176
|
+
// Preserve the expression only if evaluating it reproduces the requested value.
|
|
177
|
+
if (!Number.isFinite(multiplier) ||
|
|
178
|
+
multiplier === 0 ||
|
|
179
|
+
multiplier *
|
|
180
|
+
(expression.binding.type === 'constant'
|
|
181
|
+
? expression.binding.value
|
|
182
|
+
: NaN) !==
|
|
183
|
+
value) {
|
|
175
184
|
return numericExpression(value);
|
|
176
185
|
}
|
|
177
186
|
const factor = numericExpression(multiplier);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type { File } from '@babel/types';
|
|
2
|
-
import type { VideoConfigValues } from 'remotion';
|
|
3
|
-
export type VideoConfigIdentifierValues = Record<string,
|
|
1
|
+
import type { File, Identifier } from '@babel/types';
|
|
2
|
+
import type { VideoConfigNumericBinding, VideoConfigValues } from 'remotion';
|
|
3
|
+
export type VideoConfigIdentifierValues = Map<Identifier, VideoConfigNumericBinding> | Record<string, VideoConfigNumericBinding>;
|
|
4
|
+
export declare const getVideoConfigIdentifiers: ({ ast, }: {
|
|
5
|
+
ast: File;
|
|
6
|
+
}) => Map<Identifier, VideoConfigNumericBinding>;
|
|
4
7
|
export declare const getVideoConfigIdentifierValues: ({ ast, videoConfigValues, }: {
|
|
5
8
|
ast: File;
|
|
6
9
|
videoConfigValues: VideoConfigValues | null;
|