@remotion/studio 4.0.509 → 4.0.510

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 (48) hide show
  1. package/dist/components/Canvas.js +6 -3
  2. package/dist/components/CompositionSelectorItem.js +1 -1
  3. package/dist/components/InspectorOpenInEditor.js +11 -0
  4. package/dist/components/InspectorPanel/CompositionMetadata.js +23 -1
  5. package/dist/components/QuickSwitcher/asset-search.js +1 -0
  6. package/dist/components/SelectedOutlineCropControls.js +1 -1
  7. package/dist/components/SelectedOutlinePolygon.js +2 -1
  8. package/dist/components/Timeline/EasingEditorModal.d.ts +8 -0
  9. package/dist/components/Timeline/EasingEditorModal.js +8 -9
  10. package/dist/components/Timeline/TimelineColorField.js +1 -6
  11. package/dist/components/Timeline/TimelineEffectItem.js +1 -1
  12. package/dist/components/Timeline/TimelineEffectPropItem.js +1 -1
  13. package/dist/components/Timeline/TimelineEnumField.js +1 -4
  14. package/dist/components/Timeline/TimelineExpandedRow.js +2 -2
  15. package/dist/components/Timeline/TimelineFieldRowContent.d.ts +2 -1
  16. package/dist/components/Timeline/TimelineFieldRowContent.js +18 -3
  17. package/dist/components/Timeline/TimelineFontFamilyField.js +1 -2
  18. package/dist/components/Timeline/TimelineKeyframeEasingLine.js +3 -2
  19. package/dist/components/Timeline/TimelineNumberField.js +4 -2
  20. package/dist/components/Timeline/TimelineRotationField.js +3 -3
  21. package/dist/components/Timeline/TimelineRowChrome.d.ts +5 -0
  22. package/dist/components/Timeline/TimelineRowChrome.js +14 -9
  23. package/dist/components/Timeline/TimelineRowLayoutContext.d.ts +1 -0
  24. package/dist/components/Timeline/TimelineRowLayoutContext.js +4 -1
  25. package/dist/components/Timeline/TimelineScaleField.js +4 -0
  26. package/dist/components/Timeline/TimelineSequenceItem.js +1 -1
  27. package/dist/components/Timeline/TimelineSequencePropItem.js +1 -1
  28. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +2 -0
  29. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +63 -14
  30. package/dist/components/Timeline/TimelineTextContentField.js +1 -1
  31. package/dist/components/Timeline/get-sequence-context-menu-items.js +1 -0
  32. package/dist/components/Timeline/split-selected-timeline-item.d.ts +0 -1
  33. package/dist/components/Timeline/split-selected-timeline-item.js +5 -13
  34. package/dist/components/Timeline/timeline-field-row-layout.js +2 -2
  35. package/dist/components/Timeline/timeline-field-utils.d.ts +1 -0
  36. package/dist/components/Timeline/timeline-field-utils.js +6 -1
  37. package/dist/components/UndoRedoButtons.js +5 -3
  38. package/dist/components/get-open-in-menu-items.d.ts +2 -1
  39. package/dist/components/get-open-in-menu-items.js +28 -3
  40. package/dist/esm/{chunk-jdn6nkbk.js → chunk-axbagh08.js} +3922 -3730
  41. package/dist/esm/internals.mjs +3922 -3730
  42. package/dist/esm/previewEntry.mjs +3808 -3616
  43. package/dist/esm/renderEntry.mjs +1 -1
  44. package/dist/helpers/open-in-editor.d.ts +1 -0
  45. package/dist/helpers/open-in-editor.js +5 -1
  46. package/dist/icons/git-client.d.ts +6 -0
  47. package/dist/icons/git-client.js +8 -0
  48. package/package.json +12 -12
@@ -357,7 +357,7 @@ const TimelineSequencePropItem = ({ field, validatedLocation, rowDepth, nodePath
357
357
  ...style,
358
358
  }, children: fieldValue }));
359
359
  }
360
- const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, outerHeight: null, children: jsx_runtime_1.jsx(TimelineFieldRowContent_1.TimelineFieldRowContent, { field: field, rowDepth: rowDepth, selected: selection.selected, children: fieldValue }) }));
360
+ const row = (jsx_runtime_1.jsx(TimelineRowChrome_1.TimelineRowChrome, { depth: rowDepth, eye: jsx_runtime_1.jsx(TimelineLayerEye_1.TimelineLayerEyeSpacer, {}), keyframeControls: keyframeControls, arrow: jsx_runtime_1.jsx(TimelineExpandArrowButton_1.TimelineExpandArrowSpacer, {}), style: style, selected: selection.selected, selectable: selection.selectable, selectionItem: selection.selectionItem, onSelect: selection.onSelect, onDoubleClick: onPropertyDoubleClick, showSelectedBackground: true, containsSelection: false, isFieldRow: true, outerHeight: null, children: jsx_runtime_1.jsx(TimelineFieldRowContent_1.TimelineFieldRowContent, { field: field, rowDepth: rowDepth, selected: selection.selected, keyframeControls: keyframeControls, children: fieldValue }) }));
361
361
  return jsx_runtime_1.jsx(ContextMenu_1.ContextMenu, { getItems: getContextMenuItems, children: row });
362
362
  };
363
363
  exports.TimelineSequencePropItem = TimelineSequencePropItem;
@@ -32,7 +32,9 @@ export type TimelineSequenceFromDragTarget = {
32
32
  readonly sequenceKeyframes: TimelineSequenceKeyframeDragTarget[];
33
33
  };
34
34
  type TimelineSequenceKeyframeDragTarget = {
35
+ readonly fileName: string;
35
36
  readonly fieldKey: string;
37
+ readonly nodePath: SequencePropsSubscriptionKey;
36
38
  readonly schema: InteractivitySchema;
37
39
  readonly status: CanUpdateSequencePropStatusKeyframed;
38
40
  };
@@ -70,7 +70,15 @@ const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, })
70
70
  const sequenceKeyframes = sequenceSchema === undefined
71
71
  ? []
72
72
  : Object.entries(status.props).flatMap(([fieldKey, propStatus]) => propStatus.status === 'keyframed'
73
- ? [{ fieldKey, schema: sequenceSchema, status: propStatus }]
73
+ ? [
74
+ {
75
+ fileName: nodePath.absolutePath,
76
+ fieldKey,
77
+ nodePath,
78
+ schema: sequenceSchema,
79
+ status: propStatus,
80
+ },
81
+ ]
74
82
  : []);
75
83
  const effectKeyframes = status.effects.flatMap((effectStatus) => {
76
84
  var _a;
@@ -85,7 +93,9 @@ const getKeyframedSequenceDragTargets = ({ nodePath, sequence, propStatuses, })
85
93
  ? [
86
94
  {
87
95
  effectIndex: effectStatus.effectIndex,
96
+ fileName: nodePath.absolutePath,
88
97
  fieldKey,
98
+ nodePath,
89
99
  schema: effectSchema,
90
100
  status: propStatus,
91
101
  },
@@ -352,16 +362,16 @@ const getTimelineSequenceFromDragKeyframeMoves = ({ targets, deltaFrames, }) =>
352
362
  }
353
363
  return {
354
364
  sequenceKeyframes: targets.flatMap((target) => target.sequenceKeyframes.flatMap((keyframeTarget) => keyframeTarget.status.keyframes.map((keyframe) => ({
355
- fileName: target.fileName,
356
- nodePath: target.nodePath,
365
+ fileName: keyframeTarget.fileName,
366
+ nodePath: keyframeTarget.nodePath,
357
367
  fieldKey: keyframeTarget.fieldKey,
358
368
  fromFrame: keyframe.frame,
359
369
  toFrame: keyframe.frame + deltaFrames,
360
370
  schema: keyframeTarget.schema,
361
371
  })))),
362
372
  effectKeyframes: targets.flatMap((target) => target.effectKeyframes.flatMap((keyframeTarget) => keyframeTarget.status.keyframes.map((keyframe) => ({
363
- fileName: target.fileName,
364
- nodePath: target.nodePath,
373
+ fileName: keyframeTarget.fileName,
374
+ nodePath: keyframeTarget.nodePath,
365
375
  effectIndex: keyframeTarget.effectIndex,
366
376
  fieldKey: keyframeTarget.fieldKey,
367
377
  fromFrame: keyframe.frame,
@@ -510,6 +520,7 @@ const getTimelineSequenceFromDragTargets = ({ draggedNodePathInfo, selectedItems
510
520
  : [draggedNodePathInfo];
511
521
  const tracks = (0, calculate_timeline_1.calculateTimeline)({ sequences, overrideIdsToNodePaths });
512
522
  const targets = new Map();
523
+ const includedKeyframeNodePaths = new Set();
513
524
  for (const nodePathInfo of targetNodePathInfos) {
514
525
  const track = findSequenceTrack({ tracks, nodePathInfo });
515
526
  const originalSequence = track
@@ -527,11 +538,42 @@ const getTimelineSequenceFromDragTargets = ({ draggedNodePathInfo, selectedItems
527
538
  }
528
539
  const key = (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath);
529
540
  if (!targets.has(key)) {
530
- const { effectKeyframes, sequenceKeyframes } = getKeyframedSequenceDragTargets({
531
- nodePath,
532
- sequence: originalSequence,
533
- propStatuses,
541
+ const descendants = sequences.filter((candidate) => {
542
+ var _a;
543
+ var _b;
544
+ let parentId = candidate.id;
545
+ while (parentId !== null) {
546
+ if (parentId === originalSequence.id) {
547
+ return true;
548
+ }
549
+ parentId = (_b = (_a = sequences.find((sequence) => sequence.id === parentId)) === null || _a === void 0 ? void 0 : _a.parent) !== null && _b !== void 0 ? _b : null;
550
+ }
551
+ return false;
552
+ });
553
+ const descendantKeyframes = descendants.flatMap((sequence) => {
554
+ var _a;
555
+ const overrideId = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.overrideId;
556
+ const descendantNodePath = overrideId
557
+ ? overrideIdsToNodePaths[overrideId]
558
+ : undefined;
559
+ if (descendantNodePath === undefined) {
560
+ return [];
561
+ }
562
+ const descendantNodePathKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)(descendantNodePath);
563
+ if (includedKeyframeNodePaths.has(descendantNodePathKey)) {
564
+ return [];
565
+ }
566
+ includedKeyframeNodePaths.add(descendantNodePathKey);
567
+ return [
568
+ getKeyframedSequenceDragTargets({
569
+ nodePath: descendantNodePath,
570
+ sequence,
571
+ propStatuses,
572
+ }),
573
+ ];
534
574
  });
575
+ const effectKeyframes = descendantKeyframes.flatMap((descendant) => descendant.effectKeyframes);
576
+ const sequenceKeyframes = descendantKeyframes.flatMap((descendant) => descendant.sequenceKeyframes);
535
577
  targets.set(key, {
536
578
  canSnapToTimelineStart: originalSequence.parent === null,
537
579
  effectKeyframes,
@@ -558,9 +600,16 @@ const clearDurationDragOverrides = ({ clearDragOverrides, targets, }) => {
558
600
  const clearFromDragOverrides = ({ clearDragOverrides, clearEffectDragOverrides, targets, }) => {
559
601
  for (const target of targets) {
560
602
  clearDragOverrides(target.nodePath);
561
- const effectIndexes = new Set(target.effectKeyframes.map((keyframe) => keyframe.effectIndex));
562
- for (const effectIndex of effectIndexes) {
563
- clearEffectDragOverrides(target.nodePath, effectIndex);
603
+ for (const keyframeTarget of target.sequenceKeyframes) {
604
+ clearDragOverrides(keyframeTarget.nodePath);
605
+ }
606
+ const effectIndexes = new Set(target.effectKeyframes.map((keyframe) => `${(0, studio_shared_1.stringifySequenceSubscriptionKey)(keyframe.nodePath)}:${keyframe.effectIndex}`));
607
+ for (const keyframeTarget of target.effectKeyframes) {
608
+ const key = `${(0, studio_shared_1.stringifySequenceSubscriptionKey)(keyframeTarget.nodePath)}:${keyframeTarget.effectIndex}`;
609
+ if (!effectIndexes.delete(key)) {
610
+ continue;
611
+ }
612
+ clearEffectDragOverrides(keyframeTarget.nodePath, keyframeTarget.effectIndex);
564
613
  }
565
614
  }
566
615
  };
@@ -916,7 +965,7 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
916
965
  });
917
966
  latestRef.current.setDragOverrides(target.nodePath, 'from', remotion_1.Internals.makeStaticDragOverride(nextFrom));
918
967
  for (const keyframeTarget of target.sequenceKeyframes) {
919
- latestRef.current.setDragOverrides(target.nodePath, keyframeTarget.fieldKey, {
968
+ latestRef.current.setDragOverrides(keyframeTarget.nodePath, keyframeTarget.fieldKey, {
920
969
  type: 'keyframed',
921
970
  status: shiftKeyframedStatus({
922
971
  status: keyframeTarget.status,
@@ -925,7 +974,7 @@ const useTimelineSequenceFromDrag = ({ nodePathInfo, windowWidth, timelineDurati
925
974
  });
926
975
  }
927
976
  for (const keyframeTarget of target.effectKeyframes) {
928
- latestRef.current.setEffectDragOverrides(target.nodePath, keyframeTarget.effectIndex, keyframeTarget.fieldKey, {
977
+ latestRef.current.setEffectDragOverrides(keyframeTarget.nodePath, keyframeTarget.effectIndex, keyframeTarget.fieldKey, {
929
978
  type: 'keyframed',
930
979
  status: shiftKeyframedStatus({
931
980
  status: keyframeTarget.status,
@@ -102,6 +102,6 @@ const TimelineTextContentField = ({ effectiveValue, field, nodePath, onDragEnd,
102
102
  event.currentTarget.blur();
103
103
  }
104
104
  }, []);
105
- return (jsx_runtime_1.jsx(RemTextarea_1.RemTextarea, { ref: setInputRef, status: "ok", small: true, defaultValue: currentValue, onBlur: commitPending, onChange: onChange, onKeyDownCapture: onKeyDownCapture, style: textAreaStyle }, String((_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : '')));
105
+ return (jsx_runtime_1.jsx(RemTextarea_1.RemTextarea, { ref: setInputRef, status: "ok", small: true, defaultValue: currentValue, onBlur: commitPending, onChange: onChange, onDoubleClick: (event) => event.stopPropagation(), onKeyDownCapture: onKeyDownCapture, style: textAreaStyle }, String((_a = propStatus.codeValue) !== null && _a !== void 0 ? _a : '')));
106
106
  };
107
107
  exports.TimelineTextContentField = TimelineTextContentField;
@@ -62,6 +62,7 @@ const getSequenceContextMenuItems = ({ assetLinkInfo, canOpenInEditor, deleteDis
62
62
  (0, NotificationCenter_1.showNotification)(`Could not open file: ${err.message}`, 2000);
63
63
  });
64
64
  },
65
+ onOpenInGitClient: () => undefined,
65
66
  onOpenInTerminal: null,
66
67
  })
67
68
  : [];
@@ -8,7 +8,6 @@ export type SplitTimelineSequenceEligibility = {
8
8
  canSplit: false;
9
9
  reason: string;
10
10
  };
11
- export declare const getTimelineSequenceSplitUnsupportedReason: (componentName: string | null | undefined) => string | null;
12
11
  export declare const getTimelineSequenceSplitEligibility: ({ selection, sequence, splitFrame, propStatuses, }: {
13
12
  selection: TimelineSelection;
14
13
  sequence: TSequence | null;
@@ -1,18 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.splitSelectedTimelineItems = exports.shouldHandleTimelineSplitShortcut = exports.shouldHandleTimelineDuplicateShortcut = exports.splitTimelineSequenceFromSource = exports.getTimelineSequenceSplitEligibility = exports.getTimelineSequenceSplitUnsupportedReason = void 0;
3
+ exports.splitSelectedTimelineItems = exports.shouldHandleTimelineSplitShortcut = exports.shouldHandleTimelineDuplicateShortcut = exports.splitTimelineSequenceFromSource = exports.getTimelineSequenceSplitEligibility = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
4
5
  const remotion_1 = require("remotion");
5
6
  const call_api_1 = require("../call-api");
6
7
  const NotificationCenter_1 = require("../Notifications/NotificationCenter");
7
8
  const find_track_for_node_path_info_1 = require("./find-track-for-node-path-info");
8
- const getTimelineSequenceSplitUnsupportedReason = (componentName) => {
9
- if (componentName === '<TransitionSeries.Sequence>' ||
10
- componentName === '<TransitionSeries.Overlay>') {
11
- return `${componentName} cannot be split from source`;
12
- }
13
- return null;
14
- };
15
- exports.getTimelineSequenceSplitUnsupportedReason = getTimelineSequenceSplitUnsupportedReason;
16
9
  const staticNumberish = (status) => {
17
10
  if (!status) {
18
11
  return true;
@@ -21,7 +14,6 @@ const staticNumberish = (status) => {
21
14
  (typeof status.codeValue === 'number' || status.codeValue === undefined));
22
15
  };
23
16
  const getTimelineSequenceSplitEligibility = ({ selection, sequence, splitFrame, propStatuses, }) => {
24
- var _a;
25
17
  if (selection.type !== 'sequence') {
26
18
  return {
27
19
  canSplit: false,
@@ -46,11 +38,10 @@ const getTimelineSequenceSplitEligibility = ({ selection, sequence, splitFrame,
46
38
  reason: 'Series.Sequence clips cannot be split from source',
47
39
  };
48
40
  }
49
- const unsupportedReason = (0, exports.getTimelineSequenceSplitUnsupportedReason)((_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.componentName);
50
- if (unsupportedReason) {
41
+ if (!(0, studio_shared_1.hasSequenceTimingTraits)(selection.nodePathInfo.sequenceSubscriptionKey.sequenceKeys)) {
51
42
  return {
52
43
  canSplit: false,
53
- reason: unsupportedReason,
44
+ reason: 'Sequence does not expose timing traits that can be split',
54
45
  };
55
46
  }
56
47
  const { nodePathInfo } = selection;
@@ -101,6 +92,7 @@ const splitTimelineSequenceFromSource = ({ nodePathInfo, splitFrame, }) => {
101
92
  return (0, call_api_1.callApi)('/api/split-jsx-sequence', {
102
93
  fileName: nodePath.absolutePath,
103
94
  nodePath: nodePath.nodePath,
95
+ sequenceKeys: nodePath.sequenceKeys,
104
96
  splitFrame,
105
97
  })
106
98
  .then((result) => {
@@ -33,9 +33,9 @@ exports.timelineFieldValueColumnStyle = {
33
33
  };
34
34
  exports.timelineCompactStackedFieldValueColumnStyle = {
35
35
  ...exports.timelineFieldValueColumnStyle,
36
- marginBottom: -2,
36
+ marginBottom: -3,
37
37
  position: 'relative',
38
- top: -2,
38
+ top: -3,
39
39
  };
40
40
  exports.timelineStackedFieldContentStyle = {
41
41
  alignSelf: 'stretch',
@@ -11,3 +11,4 @@ export declare const formatTimelineNumber: ({ decimalPlaces, fixed, value, }: {
11
11
  }) => string;
12
12
  export declare const normalizeTimelineNumber: (value: number) => number;
13
13
  export declare const draggerStyle: React.CSSProperties;
14
+ export declare const leftAlignedDraggerStyle: React.CSSProperties;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.draggerStyle = exports.normalizeTimelineNumber = exports.formatTimelineNumber = exports.roundToDecimalPlaces = exports.getTimelineDisplayDecimalPlaces = exports.getDecimalPlaces = void 0;
3
+ exports.leftAlignedDraggerStyle = exports.draggerStyle = exports.normalizeTimelineNumber = exports.formatTimelineNumber = exports.roundToDecimalPlaces = exports.getTimelineDisplayDecimalPlaces = exports.getDecimalPlaces = void 0;
4
4
  const getDecimalPlaces = (num) => {
5
5
  const [coefficient, exponent] = String(num).toLowerCase().split('e');
6
6
  const decimalIndex = coefficient.indexOf('.');
@@ -35,3 +35,8 @@ exports.normalizeTimelineNumber = normalizeTimelineNumber;
35
35
  exports.draggerStyle = {
36
36
  width: 80,
37
37
  };
38
+ exports.leftAlignedDraggerStyle = {
39
+ paddingBottom: 2,
40
+ paddingLeft: 0,
41
+ paddingTop: 2,
42
+ };
@@ -69,6 +69,8 @@ const UndoRedoButtons = () => {
69
69
  });
70
70
  }, []);
71
71
  (0, react_1.useEffect)(() => {
72
+ // Visual controls such as the color picker commit edits while their popup
73
+ // remains open. Keep undo and redo available in that higher z-index context.
72
74
  const undo = keybindings.registerKeybinding({
73
75
  event: 'keydown',
74
76
  key: 'z',
@@ -83,7 +85,7 @@ const UndoRedoButtons = () => {
83
85
  },
84
86
  preventDefault: true,
85
87
  triggerIfInputFieldFocused: false,
86
- keepRegisteredWhenNotHighestContext: false,
88
+ keepRegisteredWhenNotHighestContext: true,
87
89
  });
88
90
  const redoWithShiftZ = keybindings.registerKeybinding({
89
91
  event: 'keydown',
@@ -99,7 +101,7 @@ const UndoRedoButtons = () => {
99
101
  },
100
102
  preventDefault: true,
101
103
  triggerIfInputFieldFocused: false,
102
- keepRegisteredWhenNotHighestContext: false,
104
+ keepRegisteredWhenNotHighestContext: true,
103
105
  });
104
106
  const redoWithY = is_mac_1.isMac
105
107
  ? null
@@ -114,7 +116,7 @@ const UndoRedoButtons = () => {
114
116
  },
115
117
  preventDefault: true,
116
118
  triggerIfInputFieldFocused: false,
117
- keepRegisteredWhenNotHighestContext: false,
119
+ keepRegisteredWhenNotHighestContext: true,
118
120
  });
119
121
  return () => {
120
122
  undo.unregister();
@@ -2,7 +2,7 @@ import type { TerminalId } from '@remotion/studio-shared';
2
2
  import type { EditorPickerId, GetDefaultCodingAgentInfoResponse, GetDefaultEditorInfoResponse } from '@remotion/studio-shared';
3
3
  import type { OriginalPosition } from '../error-overlay/react-overlay/utils/get-source-map';
4
4
  import type { ComboboxValue } from './NewComposition/ComboBox';
5
- export declare const getOpenInMenuItems: ({ codingAgentInfo, editorDisabled, editorInfo, excludeCodingAgentId, excludeEditorId, fileManagerDisabled, folder, location, onConfigureApps, onOpenInCodingAgent, onOpenInEditor, onOpenInFileExplorer, onOpenInTerminal, }: {
5
+ export declare const getOpenInMenuItems: ({ codingAgentInfo, editorDisabled, editorInfo, excludeCodingAgentId, excludeEditorId, fileManagerDisabled, folder, location, onConfigureApps, onOpenInCodingAgent, onOpenInEditor, onOpenInFileExplorer, onOpenInGitClient, onOpenInTerminal, }: {
6
6
  readonly codingAgentInfo: GetDefaultCodingAgentInfoResponse | null;
7
7
  readonly editorDisabled: boolean;
8
8
  readonly editorInfo: GetDefaultEditorInfoResponse | null;
@@ -15,5 +15,6 @@ export declare const getOpenInMenuItems: ({ codingAgentInfo, editorDisabled, edi
15
15
  readonly onOpenInCodingAgent: (codingAgentId: "claude-code" | "codex" | "copilot" | "cursor", codingAgentName: string) => void;
16
16
  readonly onOpenInEditor: (editorId: EditorPickerId) => void;
17
17
  readonly onOpenInFileExplorer: () => void;
18
+ readonly onOpenInGitClient: (gitClientId: "github-desktop") => void;
18
19
  readonly onOpenInTerminal: ((terminalId: TerminalId) => void) | null;
19
20
  }) => ComboboxValue[];
@@ -7,6 +7,7 @@ const get_file_manager_name_1 = require("../helpers/get-file-manager-name");
7
7
  const get_git_menu_item_1 = require("../helpers/get-git-menu-item");
8
8
  const editor_1 = require("../icons/editor");
9
9
  const finder_1 = require("../icons/finder");
10
+ const git_client_1 = require("../icons/git-client");
10
11
  const github_1 = require("../icons/github");
11
12
  const terminal_1 = require("../icons/terminal");
12
13
  const CodingAgentIcon_1 = require("./CodingAgentIcon");
@@ -16,8 +17,8 @@ const menuLabel = {
16
17
  fontSize: 13,
17
18
  lineHeight: '16px',
18
19
  };
19
- const getOpenInMenuItems = ({ codingAgentInfo, editorDisabled, editorInfo, excludeCodingAgentId, excludeEditorId, fileManagerDisabled, folder, location, onConfigureApps, onOpenInCodingAgent, onOpenInEditor, onOpenInFileExplorer, onOpenInTerminal, }) => {
20
- var _a, _b, _c;
20
+ const getOpenInMenuItems = ({ codingAgentInfo, editorDisabled, editorInfo, excludeCodingAgentId, excludeEditorId, fileManagerDisabled, folder, location, onConfigureApps, onOpenInCodingAgent, onOpenInEditor, onOpenInFileExplorer, onOpenInGitClient, onOpenInTerminal, }) => {
21
+ var _a, _b, _c, _d;
21
22
  const showFinder = window.remotion_fileSystemPlatform === 'darwin';
22
23
  const fileManagerName = (0, get_file_manager_name_1.getFileManagerName)(window.remotion_fileSystemPlatform);
23
24
  const editors = ((_a = editorInfo === null || editorInfo === void 0 ? void 0 : editorInfo.installedEditors) !== null && _a !== void 0 ? _a : [])
@@ -52,6 +53,7 @@ const getOpenInMenuItems = ({ codingAgentInfo, editorDisabled, editorInfo, exclu
52
53
  value: `coding-agent-${codingAgent.id}`,
53
54
  }));
54
55
  const terminals = folder ? ((_c = codingAgentInfo === null || codingAgentInfo === void 0 ? void 0 : codingAgentInfo.installedTerminals) !== null && _c !== void 0 ? _c : []) : [];
56
+ const gitClients = folder ? ((_d = codingAgentInfo === null || codingAgentInfo === void 0 ? void 0 : codingAgentInfo.installedGitClients) !== null && _d !== void 0 ? _d : []) : [];
55
57
  const gitHubItem = window.remotion_gitSource
56
58
  ? {
57
59
  id: 'open-in-github',
@@ -94,7 +96,10 @@ const getOpenInMenuItems = ({ codingAgentInfo, editorDisabled, editorInfo, exclu
94
96
  }
95
97
  : null,
96
98
  ].filter(no_react_1.NoReactInternals.truthy);
97
- const hasCategorizedApps = editors.length > 0 || codingAgents.length > 0 || terminals.length > 0;
99
+ const hasCategorizedApps = editors.length > 0 ||
100
+ codingAgents.length > 0 ||
101
+ terminals.length > 0 ||
102
+ gitClients.length > 0;
98
103
  return [
99
104
  ...(editors.length > 0
100
105
  ? [
@@ -136,6 +141,26 @@ const getOpenInMenuItems = ({ codingAgentInfo, editorDisabled, editorInfo, exclu
136
141
  })),
137
142
  ]
138
143
  : []),
144
+ ...(gitClients.length > 0
145
+ ? [
146
+ {
147
+ type: 'section-header',
148
+ id: 'git-client-header',
149
+ label: 'Git Client',
150
+ },
151
+ ...gitClients.map((gitClient) => ({
152
+ id: `open-in-git-client-${gitClient.id}`,
153
+ keyHint: null,
154
+ label: jsx_runtime_1.jsx("span", { style: menuLabel, children: gitClient.name }),
155
+ leftItem: jsx_runtime_1.jsx(git_client_1.GitClientIcon, { gitClientId: gitClient.id, size: 18 }),
156
+ onClick: () => onOpenInGitClient(gitClient.id),
157
+ quickSwitcherLabel: null,
158
+ subMenu: null,
159
+ type: 'item',
160
+ value: `git-client-${gitClient.id}`,
161
+ })),
162
+ ]
163
+ : []),
139
164
  ...(systemApps.length > 0
140
165
  ? [
141
166
  ...(hasCategorizedApps