@industry-theme/xterm-terminal-panel 0.2.2 → 0.2.4

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/index.js CHANGED
@@ -800,10 +800,268 @@ function useThemedTerminal() {
800
800
  getCSSVariables
801
801
  };
802
802
  }
803
- // src/panels/TerminalPanel.tsx
803
+ // src/components/TabBar/TabBar.tsx
804
+ import { useTheme as useTheme4 } from "@principal-ade/industry-theme";
805
+ import { Plus } from "lucide-react";
806
+ import { useState as useState2 } from "react";
807
+
808
+ // src/components/TabBar/TabButton.tsx
804
809
  import { useTheme as useTheme3 } from "@principal-ade/industry-theme";
810
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
811
+ var TabButton = ({
812
+ tab,
813
+ isActive,
814
+ isHovered,
815
+ onMouseEnter,
816
+ onMouseLeave,
817
+ onClick,
818
+ onClose,
819
+ keyboardHint,
820
+ renderAccessory
821
+ }) => {
822
+ const { theme } = useTheme3();
823
+ const showCloseButton = isHovered || isActive;
824
+ const closable = tab.closable !== false;
825
+ return /* @__PURE__ */ jsxs2("div", {
826
+ onMouseEnter,
827
+ onMouseLeave,
828
+ onClick,
829
+ style: {
830
+ display: "flex",
831
+ alignItems: "center",
832
+ justifyContent: "center",
833
+ gap: "6px",
834
+ padding: "6px 8px",
835
+ backgroundColor: isActive ? theme.colors.background : theme.colors.backgroundSecondary,
836
+ cursor: "pointer",
837
+ fontSize: theme.fontSizes[1],
838
+ fontWeight: isActive ? theme.fontWeights.semibold : theme.fontWeights.body,
839
+ fontFamily: theme.fonts.body,
840
+ color: isActive ? theme.colors.text : theme.colors.textSecondary,
841
+ whiteSpace: "nowrap",
842
+ transition: "all 0.2s",
843
+ flex: 1,
844
+ minWidth: 0,
845
+ height: "100%",
846
+ position: "relative",
847
+ boxSizing: "border-box"
848
+ },
849
+ children: [
850
+ closable && showCloseButton && /* @__PURE__ */ jsx3("button", {
851
+ onClick: (e) => {
852
+ e.stopPropagation();
853
+ onClose();
854
+ },
855
+ style: {
856
+ display: "flex",
857
+ alignItems: "center",
858
+ justifyContent: "center",
859
+ width: "16px",
860
+ height: "16px",
861
+ borderRadius: "3px",
862
+ border: "none",
863
+ backgroundColor: "transparent",
864
+ cursor: "pointer",
865
+ color: theme.colors.textSecondary,
866
+ padding: 0,
867
+ position: "absolute",
868
+ left: "8px"
869
+ },
870
+ onMouseEnter: (e) => {
871
+ e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
872
+ },
873
+ onMouseLeave: (e) => {
874
+ e.currentTarget.style.backgroundColor = "transparent";
875
+ },
876
+ title: "Close (⌘W)",
877
+ children: "×"
878
+ }),
879
+ tab.icon && /* @__PURE__ */ jsx3("div", {
880
+ style: { flexShrink: 0, display: "flex", alignItems: "center" },
881
+ children: tab.icon
882
+ }),
883
+ /* @__PURE__ */ jsx3("span", {
884
+ style: {
885
+ overflow: "hidden",
886
+ textOverflow: "ellipsis",
887
+ whiteSpace: "nowrap"
888
+ },
889
+ title: tab.label,
890
+ children: tab.label
891
+ }),
892
+ renderAccessory ? renderAccessory(tab) : keyboardHint && /* @__PURE__ */ jsx3("span", {
893
+ style: {
894
+ fontSize: theme.fontSizes[0],
895
+ color: theme.colors.textSecondary,
896
+ opacity: 0.6,
897
+ flexShrink: 0
898
+ },
899
+ children: keyboardHint
900
+ })
901
+ ]
902
+ });
903
+ };
904
+ TabButton.displayName = "TabButton";
905
+
906
+ // src/components/TabBar/TabBar.tsx
907
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
908
+ var TabBar = ({
909
+ tabs,
910
+ activeTabId,
911
+ onTabClick,
912
+ onTabClose,
913
+ onNewTab,
914
+ leftSection,
915
+ rightSection,
916
+ renderTabAccessory,
917
+ className,
918
+ showKeyboardHints = true
919
+ }) => {
920
+ const { theme } = useTheme4();
921
+ const [hoveredTabId, setHoveredTabId] = useState2(null);
922
+ return /* @__PURE__ */ jsxs3("div", {
923
+ className,
924
+ style: {
925
+ display: "flex",
926
+ alignItems: "stretch",
927
+ height: "40px",
928
+ flexShrink: 0,
929
+ boxSizing: "border-box"
930
+ },
931
+ children: [
932
+ leftSection && /* @__PURE__ */ jsx4("div", {
933
+ style: {
934
+ display: "flex",
935
+ alignItems: "center",
936
+ gap: "4px",
937
+ padding: "0 8px",
938
+ backgroundColor: theme.colors.backgroundSecondary,
939
+ borderRight: `1px solid ${theme.colors.border}`,
940
+ borderBottom: `1px solid ${theme.colors.border}`,
941
+ boxSizing: "border-box"
942
+ },
943
+ children: leftSection
944
+ }),
945
+ /* @__PURE__ */ jsx4("div", {
946
+ style: {
947
+ display: "flex",
948
+ alignItems: "center",
949
+ flex: 1,
950
+ overflow: "hidden",
951
+ backgroundColor: theme.colors.backgroundSecondary,
952
+ borderBottom: `1px solid ${theme.colors.border}`,
953
+ boxSizing: "border-box"
954
+ },
955
+ children: tabs.map((tab, index) => /* @__PURE__ */ jsx4(TabButton, {
956
+ tab,
957
+ isActive: tab.id === activeTabId,
958
+ isHovered: tab.id === hoveredTabId,
959
+ onMouseEnter: () => setHoveredTabId(tab.id),
960
+ onMouseLeave: () => setHoveredTabId(null),
961
+ onClick: () => onTabClick(tab.id),
962
+ onClose: () => onTabClose(tab.id),
963
+ keyboardHint: showKeyboardHints && index < 9 ? `⌘ ${index + 1}` : undefined,
964
+ renderAccessory: renderTabAccessory
965
+ }, tab.id))
966
+ }),
967
+ rightSection !== undefined ? rightSection && /* @__PURE__ */ jsx4("div", {
968
+ style: {
969
+ display: "flex",
970
+ alignItems: "center",
971
+ gap: "4px",
972
+ padding: "0 8px",
973
+ backgroundColor: theme.colors.backgroundSecondary,
974
+ borderLeft: `1px solid ${theme.colors.border}`,
975
+ borderBottom: `1px solid ${theme.colors.border}`,
976
+ boxSizing: "border-box"
977
+ },
978
+ children: rightSection
979
+ }) : onNewTab && /* @__PURE__ */ jsx4("div", {
980
+ style: {
981
+ display: "flex",
982
+ alignItems: "center",
983
+ gap: "4px",
984
+ padding: "0 8px",
985
+ backgroundColor: theme.colors.backgroundSecondary,
986
+ borderLeft: `1px solid ${theme.colors.border}`,
987
+ borderBottom: `1px solid ${theme.colors.border}`,
988
+ boxSizing: "border-box"
989
+ },
990
+ children: /* @__PURE__ */ jsx4("button", {
991
+ onClick: onNewTab,
992
+ style: {
993
+ display: "flex",
994
+ alignItems: "center",
995
+ justifyContent: "center",
996
+ width: "28px",
997
+ height: "28px",
998
+ border: "none",
999
+ borderRadius: "4px",
1000
+ backgroundColor: "transparent",
1001
+ cursor: "pointer",
1002
+ color: theme.colors.textSecondary
1003
+ },
1004
+ onMouseEnter: (e) => {
1005
+ e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
1006
+ },
1007
+ onMouseLeave: (e) => {
1008
+ e.currentTarget.style.backgroundColor = "transparent";
1009
+ },
1010
+ title: "New Tab (⌘T)",
1011
+ children: /* @__PURE__ */ jsx4(Plus, {
1012
+ size: 14
1013
+ })
1014
+ })
1015
+ })
1016
+ ]
1017
+ });
1018
+ };
1019
+ TabBar.displayName = "TabBar";
1020
+ // src/types/mixed-tab.ts
1021
+ function isTabOfType(tab, contentType) {
1022
+ return tab.contentType === contentType;
1023
+ }
1024
+ // src/hooks/useTabKeyboardShortcuts.ts
1025
+ import { useEffect as useEffect2 } from "react";
1026
+ var useTabKeyboardShortcuts = ({
1027
+ onNewTab,
1028
+ onCloseTab,
1029
+ onSwitchToTab,
1030
+ enabled = true
1031
+ }) => {
1032
+ useEffect2(() => {
1033
+ if (!enabled)
1034
+ return;
1035
+ const handleKeyDown = (e) => {
1036
+ const isCmdOrCtrl = e.metaKey || e.ctrlKey;
1037
+ if (isCmdOrCtrl && e.key === "t" && onNewTab) {
1038
+ e.preventDefault();
1039
+ e.stopPropagation();
1040
+ onNewTab();
1041
+ return;
1042
+ }
1043
+ if (isCmdOrCtrl && e.key === "w" && onCloseTab) {
1044
+ e.preventDefault();
1045
+ e.stopPropagation();
1046
+ onCloseTab();
1047
+ return;
1048
+ }
1049
+ if (isCmdOrCtrl && /^[1-9]$/.test(e.key) && onSwitchToTab) {
1050
+ e.preventDefault();
1051
+ e.stopPropagation();
1052
+ const index = parseInt(e.key, 10) - 1;
1053
+ onSwitchToTab(index);
1054
+ return;
1055
+ }
1056
+ };
1057
+ window.addEventListener("keydown", handleKeyDown);
1058
+ return () => window.removeEventListener("keydown", handleKeyDown);
1059
+ }, [enabled, onNewTab, onCloseTab, onSwitchToTab]);
1060
+ };
1061
+ // src/panels/TerminalPanel.tsx
1062
+ import { useTheme as useTheme5 } from "@principal-ade/industry-theme";
805
1063
  import { Lock, Unlock, ArrowDown } from "lucide-react";
806
- import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
1064
+ import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
807
1065
 
808
1066
  // src/panel-types/index.ts
809
1067
  function getTerminalSessions(context) {
@@ -838,19 +1096,19 @@ function getTerminalSlice(context) {
838
1096
  }
839
1097
 
840
1098
  // src/panels/TerminalPanel.tsx
841
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1099
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
842
1100
  var TerminalPanel = ({
843
1101
  context,
844
1102
  actions,
845
1103
  events: _events,
846
1104
  terminalScope = "repository"
847
1105
  }) => {
848
- const { theme } = useTheme3();
849
- const [sessionId, setSessionId] = useState2(null);
850
- const [error, setError] = useState2(null);
851
- const [isInitializing, setIsInitializing] = useState2(true);
852
- const [usingMessagePort, setUsingMessagePort] = useState2(false);
853
- const [scrollPosition, setScrollPosition] = useState2({
1106
+ const { theme } = useTheme5();
1107
+ const [sessionId, setSessionId] = useState3(null);
1108
+ const [error, setError] = useState3(null);
1109
+ const [isInitializing, setIsInitializing] = useState3(true);
1110
+ const [usingMessagePort, setUsingMessagePort] = useState3(false);
1111
+ const [scrollPosition, setScrollPosition] = useState3({
854
1112
  isAtTop: false,
855
1113
  isAtBottom: true,
856
1114
  isScrollLocked: false
@@ -859,7 +1117,7 @@ var TerminalPanel = ({
859
1117
  const dataPortRef = useRef2(null);
860
1118
  const terminalDirectory = getTerminalDirectory(context, terminalScope);
861
1119
  const pendingSessionIdRef = useRef2(null);
862
- useEffect2(() => {
1120
+ useEffect3(() => {
863
1121
  let mounted = true;
864
1122
  let unsubscribePortReady = null;
865
1123
  const initTerminal = async () => {
@@ -917,7 +1175,7 @@ var TerminalPanel = ({
917
1175
  }
918
1176
  };
919
1177
  }, []);
920
- useEffect2(() => {
1178
+ useEffect3(() => {
921
1179
  if (usingMessagePort)
922
1180
  return;
923
1181
  if (!sessionId)
@@ -930,7 +1188,7 @@ var TerminalPanel = ({
930
1188
  }, 5000);
931
1189
  return () => clearTimeout(timeout);
932
1190
  }, [sessionId, usingMessagePort]);
933
- useEffect2(() => {
1191
+ useEffect3(() => {
934
1192
  if (!usingMessagePort || !dataPortRef.current)
935
1193
  return;
936
1194
  const port = dataPortRef.current;
@@ -988,7 +1246,7 @@ var TerminalPanel = ({
988
1246
  hasNotifiedPtyRef.current = true;
989
1247
  }
990
1248
  };
991
- useEffect2(() => {
1249
+ useEffect3(() => {
992
1250
  hasNotifiedPtyRef.current = false;
993
1251
  }, [sessionId]);
994
1252
  const handleScrollPositionChange = (position) => {
@@ -996,7 +1254,7 @@ var TerminalPanel = ({
996
1254
  };
997
1255
  const sessionInfo = sessionId ? getTerminalSession(context, sessionId) : undefined;
998
1256
  if (error) {
999
- return /* @__PURE__ */ jsxs2("div", {
1257
+ return /* @__PURE__ */ jsxs4("div", {
1000
1258
  style: {
1001
1259
  padding: "20px",
1002
1260
  color: "#ef4444",
@@ -1009,11 +1267,11 @@ var TerminalPanel = ({
1009
1267
  gap: "10px"
1010
1268
  },
1011
1269
  children: [
1012
- /* @__PURE__ */ jsx3("div", {
1270
+ /* @__PURE__ */ jsx5("div", {
1013
1271
  style: { fontSize: "16px", fontWeight: "bold" },
1014
1272
  children: "Terminal Error"
1015
1273
  }),
1016
- /* @__PURE__ */ jsx3("div", {
1274
+ /* @__PURE__ */ jsx5("div", {
1017
1275
  style: { fontSize: "14px", opacity: 0.8 },
1018
1276
  children: error
1019
1277
  })
@@ -1021,7 +1279,7 @@ var TerminalPanel = ({
1021
1279
  });
1022
1280
  }
1023
1281
  if (isInitializing || !sessionId) {
1024
- return /* @__PURE__ */ jsx3("div", {
1282
+ return /* @__PURE__ */ jsx5("div", {
1025
1283
  style: {
1026
1284
  padding: "20px",
1027
1285
  color: "#a0a0a0",
@@ -1047,10 +1305,10 @@ var TerminalPanel = ({
1047
1305
  terminalRef.current?.scrollToBottom();
1048
1306
  }
1049
1307
  };
1050
- return /* @__PURE__ */ jsxs2("div", {
1308
+ return /* @__PURE__ */ jsxs4("div", {
1051
1309
  style: { height: "100%", width: "100%", display: "flex", flexDirection: "column" },
1052
1310
  children: [
1053
- /* @__PURE__ */ jsxs2("div", {
1311
+ /* @__PURE__ */ jsxs4("div", {
1054
1312
  style: {
1055
1313
  display: "flex",
1056
1314
  gap: "8px",
@@ -1060,7 +1318,7 @@ var TerminalPanel = ({
1060
1318
  alignItems: "center"
1061
1319
  },
1062
1320
  children: [
1063
- /* @__PURE__ */ jsxs2("span", {
1321
+ /* @__PURE__ */ jsxs4("span", {
1064
1322
  style: {
1065
1323
  fontSize: "12px",
1066
1324
  color: theme.colors.textSecondary,
@@ -1073,7 +1331,7 @@ var TerminalPanel = ({
1073
1331
  sessionInfo?.shell
1074
1332
  ]
1075
1333
  }),
1076
- /* @__PURE__ */ jsxs2("button", {
1334
+ /* @__PURE__ */ jsxs4("button", {
1077
1335
  onClick: handleToggleScrollLock,
1078
1336
  style: {
1079
1337
  display: "flex",
@@ -1092,17 +1350,17 @@ var TerminalPanel = ({
1092
1350
  onMouseLeave: (e) => e.currentTarget.style.opacity = "1",
1093
1351
  title: scrollPosition.isScrollLocked ? "Click to unlock scroll" : "Click to lock scroll to bottom",
1094
1352
  children: [
1095
- scrollPosition.isScrollLocked ? /* @__PURE__ */ jsx3(Lock, {
1353
+ scrollPosition.isScrollLocked ? /* @__PURE__ */ jsx5(Lock, {
1096
1354
  size: 12
1097
- }) : /* @__PURE__ */ jsx3(Unlock, {
1355
+ }) : /* @__PURE__ */ jsx5(Unlock, {
1098
1356
  size: 12
1099
1357
  }),
1100
- /* @__PURE__ */ jsx3("span", {
1358
+ /* @__PURE__ */ jsx5("span", {
1101
1359
  children: scrollPosition.isScrollLocked ? "Locked" : "Unlocked"
1102
1360
  })
1103
1361
  ]
1104
1362
  }),
1105
- /* @__PURE__ */ jsxs2("button", {
1363
+ /* @__PURE__ */ jsxs4("button", {
1106
1364
  onClick: handleScrollToBottom,
1107
1365
  disabled: scrollPosition.isAtBottom,
1108
1366
  style: {
@@ -1123,19 +1381,19 @@ var TerminalPanel = ({
1123
1381
  onMouseLeave: (e) => !scrollPosition.isAtBottom && (e.currentTarget.style.opacity = "1"),
1124
1382
  title: "Scroll to bottom and lock",
1125
1383
  children: [
1126
- /* @__PURE__ */ jsx3(ArrowDown, {
1384
+ /* @__PURE__ */ jsx5(ArrowDown, {
1127
1385
  size: 12
1128
1386
  }),
1129
- /* @__PURE__ */ jsx3("span", {
1387
+ /* @__PURE__ */ jsx5("span", {
1130
1388
  children: "Bottom"
1131
1389
  })
1132
1390
  ]
1133
1391
  })
1134
1392
  ]
1135
1393
  }),
1136
- /* @__PURE__ */ jsx3("div", {
1394
+ /* @__PURE__ */ jsx5("div", {
1137
1395
  style: { flex: 1 },
1138
- children: /* @__PURE__ */ jsx3(ThemedTerminalWithProvider, {
1396
+ children: /* @__PURE__ */ jsx5(ThemedTerminalWithProvider, {
1139
1397
  ref: terminalRef,
1140
1398
  onData: handleTerminalData,
1141
1399
  onResize: handleTerminalResize,
@@ -1153,28 +1411,28 @@ var TerminalPanel = ({
1153
1411
  });
1154
1412
  };
1155
1413
  // src/panels/TabbedTerminalPanel.tsx
1156
- import { useTheme as useTheme4 } from "@principal-ade/industry-theme";
1157
- import { Terminal as TerminalIcon2, X as X2, Plus, Lock as Lock2, Unlock as Unlock2, Box, Boxes } from "lucide-react";
1158
- import React, {
1159
- useState as useState3,
1414
+ import { useTheme as useTheme6 } from "@principal-ade/industry-theme";
1415
+ import { Terminal as TerminalIcon2, Lock as Lock2, Unlock as Unlock2, Box, Boxes } from "lucide-react";
1416
+ import React2, {
1417
+ useState as useState4,
1160
1418
  useCallback as useCallback2,
1161
- useEffect as useEffect3,
1419
+ useEffect as useEffect4,
1162
1420
  useRef as useRef3
1163
1421
  } from "react";
1164
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1422
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1165
1423
  function TerminalTabContentInner(props, ref) {
1166
1424
  const { tab, sessionId, isActive, isVisible, actions, events, terminalContext, onSessionCreated, onScrollPositionChange, isForeign = false } = props;
1167
1425
  const terminalRef = useRef3(null);
1168
- const [localSessionId, setLocalSessionId] = useState3(sessionId);
1169
- const [isInitialized, setIsInitialized] = useState3(false);
1426
+ const [localSessionId, setLocalSessionId] = useState4(sessionId);
1427
+ const [isInitialized, setIsInitialized] = useState4(false);
1170
1428
  const hasInitializedRef = useRef3(false);
1171
- const [scrollPosition, setScrollPosition] = useState3({
1429
+ const [scrollPosition, setScrollPosition] = useState4({
1172
1430
  isAtTop: false,
1173
1431
  isAtBottom: true,
1174
1432
  isScrollLocked: false
1175
1433
  });
1176
- const [shouldRenderTerminal, setShouldRenderTerminal] = useState3(true);
1177
- const [ownerWindowId, setOwnerWindowId] = useState3(null);
1434
+ const [shouldRenderTerminal, setShouldRenderTerminal] = useState4(true);
1435
+ const [ownerWindowId, setOwnerWindowId] = useState4(null);
1178
1436
  const needsRefreshOnResizeRef = useRef3(false);
1179
1437
  const claimAndConnect = useCallback2(async (targetSessionId, force = false) => {
1180
1438
  try {
@@ -1194,7 +1452,7 @@ function TerminalTabContentInner(props, ref) {
1194
1452
  throw error;
1195
1453
  }
1196
1454
  }, [actions]);
1197
- useEffect3(() => {
1455
+ useEffect4(() => {
1198
1456
  if (hasInitializedRef.current) {
1199
1457
  return;
1200
1458
  }
@@ -1239,7 +1497,7 @@ function TerminalTabContentInner(props, ref) {
1239
1497
  mounted = false;
1240
1498
  };
1241
1499
  }, []);
1242
- useEffect3(() => {
1500
+ useEffect4(() => {
1243
1501
  if (!localSessionId || !isInitialized || !shouldRenderTerminal) {
1244
1502
  return;
1245
1503
  }
@@ -1291,7 +1549,7 @@ function TerminalTabContentInner(props, ref) {
1291
1549
  });
1292
1550
  }
1293
1551
  }, [localSessionId, events]);
1294
- useEffect3(() => {
1552
+ useEffect4(() => {
1295
1553
  if (!localSessionId || !actions.onOwnershipLost) {
1296
1554
  return;
1297
1555
  }
@@ -1341,12 +1599,12 @@ function TerminalTabContentInner(props, ref) {
1341
1599
  terminalRef.current?.scrollToBottom();
1342
1600
  }
1343
1601
  }, [scrollPosition.isScrollLocked]);
1344
- React.useImperativeHandle(ref, () => ({
1602
+ React2.useImperativeHandle(ref, () => ({
1345
1603
  scrollToBottom: handleScrollToBottom,
1346
1604
  toggleScrollLock: handleToggleScrollLock
1347
1605
  }), [handleScrollToBottom, handleToggleScrollLock]);
1348
1606
  if (!isInitialized) {
1349
- return /* @__PURE__ */ jsx4("div", {
1607
+ return /* @__PURE__ */ jsx6("div", {
1350
1608
  style: {
1351
1609
  display: isActive ? "flex" : "none",
1352
1610
  height: "100%",
@@ -1369,14 +1627,14 @@ function TerminalTabContentInner(props, ref) {
1369
1627
  ],
1370
1628
  opacity: 1
1371
1629
  } : undefined;
1372
- return /* @__PURE__ */ jsx4("div", {
1630
+ return /* @__PURE__ */ jsx6("div", {
1373
1631
  style: {
1374
1632
  display: isActive ? "flex" : "none",
1375
1633
  flexDirection: "column",
1376
1634
  height: "100%",
1377
1635
  width: "100%"
1378
1636
  },
1379
- children: /* @__PURE__ */ jsx4(ThemedTerminalWithProvider, {
1637
+ children: /* @__PURE__ */ jsx6(ThemedTerminalWithProvider, {
1380
1638
  ref: terminalRef,
1381
1639
  onData: shouldRenderTerminal ? handleData : undefined,
1382
1640
  onResize: shouldRenderTerminal ? handleResize : undefined,
@@ -1397,7 +1655,7 @@ function TerminalTabContentInner(props, ref) {
1397
1655
  });
1398
1656
  }
1399
1657
  var areTerminalTabContentPropsEqual = (prevProps, nextProps) => {
1400
- const tabEqual = prevProps.tab.id === nextProps.tab.id && prevProps.tab.directory === nextProps.tab.directory && prevProps.tab.isActive === nextProps.tab.isActive && prevProps.tab.label === nextProps.tab.label;
1658
+ const tabEqual = prevProps.tab.id === nextProps.tab.id && prevProps.tab.directory === nextProps.tab.directory && prevProps.tab.label === nextProps.tab.label;
1401
1659
  const changes = [];
1402
1660
  if (!tabEqual)
1403
1661
  changes.push("tab");
@@ -1413,8 +1671,8 @@ var areTerminalTabContentPropsEqual = (prevProps, nextProps) => {
1413
1671
  changes.push("isForeign");
1414
1672
  return changes.length === 0;
1415
1673
  };
1416
- var TerminalTabContentForwarded = React.forwardRef(TerminalTabContentInner);
1417
- var TerminalTabContent = React.memo(TerminalTabContentForwarded, areTerminalTabContentPropsEqual);
1674
+ var TerminalTabContentForwarded = React2.forwardRef(TerminalTabContentInner);
1675
+ var TerminalTabContent = React2.memo(TerminalTabContentForwarded, areTerminalTabContentPropsEqual);
1418
1676
  TerminalTabContent.displayName = "TerminalTabContent";
1419
1677
  var TabbedTerminalPanelInner = ({
1420
1678
  context: _context,
@@ -1428,22 +1686,22 @@ var TabbedTerminalPanelInner = ({
1428
1686
  initialTabs = [],
1429
1687
  showAllTerminals = false,
1430
1688
  onShowAllTerminalsChange,
1431
- tabLabelPrefix
1689
+ tabLabelPrefix,
1690
+ renderTabContent
1432
1691
  }) => {
1433
- const { theme } = useTheme4();
1434
- const [ownedTabs, setOwnedTabs] = useState3(initialTabs);
1435
- const [foreignTabs, setForeignTabs] = useState3([]);
1436
- const [activeTabId, setActiveTabId] = useState3(null);
1437
- const [sessionIds, setSessionIds] = useState3(new Map);
1438
- const [hoveredTabId, setHoveredTabId] = useState3(null);
1439
- const [scrollPositions, setScrollPositions] = useState3(new Map);
1440
- const getOwnedTabLabel = useCallback2((index, directory2) => {
1692
+ const { theme } = useTheme6();
1693
+ const [ownedTabs, setOwnedTabs] = useState4(initialTabs);
1694
+ const [foreignTabs, setForeignTabs] = useState4([]);
1695
+ const [activeTabId, setActiveTabId] = useState4(null);
1696
+ const [sessionIds, setSessionIds] = useState4(new Map);
1697
+ const [scrollPositions, setScrollPositions] = useState4(new Map);
1698
+ const getOwnedTabLabel = useCallback2((index, _directory) => {
1441
1699
  if (tabLabelPrefix) {
1442
1700
  return `${tabLabelPrefix} ${index + 1}`;
1443
1701
  }
1444
- return directory2.split("/").pop() || directory2;
1702
+ return `⌘ ${index + 1}`;
1445
1703
  }, [tabLabelPrefix]);
1446
- const tabs = React.useMemo(() => {
1704
+ const tabs = React2.useMemo(() => {
1447
1705
  const labeledOwnedTabs = ownedTabs.map((tab, index) => ({
1448
1706
  ...tab,
1449
1707
  label: getOwnedTabLabel(index, tab.directory)
@@ -1451,6 +1709,18 @@ var TabbedTerminalPanelInner = ({
1451
1709
  const sortedForeignTabs = [...foreignTabs].sort((a, b) => a.label.localeCompare(b.label));
1452
1710
  return [...labeledOwnedTabs, ...sortedForeignTabs];
1453
1711
  }, [ownedTabs, foreignTabs, getOwnedTabLabel]);
1712
+ const genericTabs = React2.useMemo(() => {
1713
+ return tabs.map((tab) => ({
1714
+ id: tab.id,
1715
+ label: tab.label,
1716
+ closable: true,
1717
+ contentType: tab.contentType,
1718
+ metadata: {
1719
+ ...tab.directory && { directory: tab.directory },
1720
+ ...tab.command && { command: tab.command }
1721
+ }
1722
+ }));
1723
+ }, [tabs]);
1454
1724
  const tabRefsMap = useRef3(new Map);
1455
1725
  const refCallbacksMap = useRef3(new Map);
1456
1726
  const getRefCallback = useCallback2((tabId) => {
@@ -1493,14 +1763,15 @@ var TabbedTerminalPanelInner = ({
1493
1763
  if (ownedSessions.length > 0 && initialTabs.length === 0) {
1494
1764
  const restoredTabs = [];
1495
1765
  const restoredSessionIds = new Map;
1496
- ownedSessions.forEach((session, index) => {
1766
+ ownedSessions.forEach((session) => {
1497
1767
  const tabId = `tab-restored-${session.id}`;
1498
1768
  const sessionCwd = session.cwd || directory;
1499
1769
  const tab = {
1500
1770
  id: tabId,
1501
1771
  label: sessionCwd.split("/").pop() || sessionCwd,
1772
+ contentType: "terminal",
1502
1773
  directory: sessionCwd,
1503
- isActive: index === 0
1774
+ closable: true
1504
1775
  };
1505
1776
  restoredTabs.push(tab);
1506
1777
  restoredSessionIds.set(tabId, session.id);
@@ -1511,7 +1782,7 @@ var TabbedTerminalPanelInner = ({
1511
1782
  onTabsChange?.(restoredTabs);
1512
1783
  } else if (initialTabs.length > 0) {
1513
1784
  setOwnedTabs(initialTabs);
1514
- setActiveTabId(initialTabs.find((t) => t.isActive)?.id || initialTabs[0]?.id || null);
1785
+ setActiveTabId(initialTabs[0]?.id || null);
1515
1786
  }
1516
1787
  } catch (err) {
1517
1788
  console.error("[TabbedTerminalPanel] Failed to restore owned sessions:", err);
@@ -1532,8 +1803,9 @@ var TabbedTerminalPanelInner = ({
1532
1803
  const tab = {
1533
1804
  id: tabId,
1534
1805
  label: sessionCwd.split("/").pop() || sessionCwd,
1806
+ contentType: "terminal",
1535
1807
  directory: sessionCwd,
1536
- isActive: false
1808
+ closable: true
1537
1809
  };
1538
1810
  foreignTabsList.push(tab);
1539
1811
  newSessionIds.set(tabId, session.id);
@@ -1559,13 +1831,13 @@ var TabbedTerminalPanelInner = ({
1559
1831
  return [];
1560
1832
  });
1561
1833
  }, []);
1562
- useEffect3(() => {
1834
+ useEffect4(() => {
1563
1835
  if (hasInitializedRef.current)
1564
1836
  return;
1565
1837
  hasInitializedRef.current = true;
1566
1838
  restoreOwnedSessions();
1567
1839
  }, []);
1568
- useEffect3(() => {
1840
+ useEffect4(() => {
1569
1841
  const handleSessionCreated2 = (event) => {
1570
1842
  const customEvent = event;
1571
1843
  const { context } = customEvent.detail || {};
@@ -1579,7 +1851,7 @@ var TabbedTerminalPanelInner = ({
1579
1851
  window.removeEventListener("terminal-session-created", handleSessionCreated2);
1580
1852
  };
1581
1853
  }, [terminalContext, restoreOwnedSessions]);
1582
- useEffect3(() => {
1854
+ useEffect4(() => {
1583
1855
  if (showAllTerminals) {
1584
1856
  fetchForeignSessions();
1585
1857
  } else {
@@ -1603,17 +1875,16 @@ var TabbedTerminalPanelInner = ({
1603
1875
  const newTab = {
1604
1876
  id: `tab-${Date.now()}`,
1605
1877
  label: label || directoryName,
1878
+ contentType: "terminal",
1606
1879
  directory: targetDir,
1607
1880
  command,
1608
- isActive: true
1881
+ closable: true
1609
1882
  };
1610
1883
  setOwnedTabs((prevTabs) => {
1611
- const updatedTabs = prevTabs.map((t) => ({ ...t, isActive: false }));
1612
- const newTabs = [...updatedTabs, newTab];
1884
+ const newTabs = [...prevTabs, newTab];
1613
1885
  onTabsChange?.(newTabs);
1614
1886
  return newTabs;
1615
1887
  });
1616
- setForeignTabs((prevTabs) => prevTabs.map((t) => ({ ...t, isActive: false })));
1617
1888
  setActiveTabId(newTab.id);
1618
1889
  }, [directory, onTabsChange]);
1619
1890
  const isForeignTab = useCallback2((tabId) => {
@@ -1648,11 +1919,8 @@ var TabbedTerminalPanelInner = ({
1648
1919
  const nextActiveId = findNextActiveTab([...ownedTabs, ...newTabs]);
1649
1920
  if (nextActiveId !== activeTabId) {
1650
1921
  setActiveTabId(nextActiveId);
1651
- if (nextActiveId) {
1652
- setOwnedTabs((owned) => owned.map((t) => ({ ...t, isActive: t.id === nextActiveId })));
1653
- }
1654
1922
  }
1655
- return newTabs.map((t) => ({ ...t, isActive: t.id === nextActiveId }));
1923
+ return newTabs;
1656
1924
  });
1657
1925
  } else {
1658
1926
  setOwnedTabs((prevTabs) => {
@@ -1660,71 +1928,74 @@ var TabbedTerminalPanelInner = ({
1660
1928
  const nextActiveId = findNextActiveTab([...newTabs, ...foreignTabs]);
1661
1929
  if (nextActiveId !== activeTabId) {
1662
1930
  setActiveTabId(nextActiveId);
1663
- if (nextActiveId) {
1664
- setForeignTabs((foreign) => foreign.map((t) => ({ ...t, isActive: t.id === nextActiveId })));
1665
- }
1666
1931
  }
1667
1932
  onTabsChange?.(newTabs);
1668
- return newTabs.map((t) => ({ ...t, isActive: t.id === nextActiveId }));
1933
+ return newTabs;
1669
1934
  });
1670
1935
  }
1671
1936
  }, [activeTabId, sessionIds, actions, onTabsChange, isForeignTab, ownedTabs, foreignTabs]);
1672
1937
  const handleSessionCreated = useCallback2((tabId, sessionId) => {
1673
1938
  setSessionIds((prev) => new Map(prev).set(tabId, sessionId));
1674
1939
  }, []);
1675
- const tabsRef = useRef3(tabs);
1676
- const activeTabIdRef = useRef3(activeTabId);
1677
- const addNewTabRef = useRef3(addNewTab);
1678
- const closeTabRef = useRef3(closeTab);
1679
- const switchTabRef = useRef3(switchTab);
1680
- useEffect3(() => {
1681
- tabsRef.current = tabs;
1682
- activeTabIdRef.current = activeTabId;
1683
- addNewTabRef.current = addNewTab;
1684
- closeTabRef.current = closeTab;
1685
- switchTabRef.current = switchTab;
1686
- }, [tabs, activeTabId, addNewTab, closeTab, switchTab]);
1687
- useEffect3(() => {
1688
- const handleKeyDown = (e) => {
1689
- if ((e.metaKey || e.ctrlKey) && e.key === "t") {
1690
- e.preventDefault();
1691
- e.stopPropagation();
1692
- if (isCreatingTabRef.current)
1693
- return;
1694
- isCreatingTabRef.current = true;
1695
- addNewTabRef.current?.();
1696
- setTimeout(() => {
1697
- isCreatingTabRef.current = false;
1698
- }, 500);
1699
- return;
1700
- }
1701
- if ((e.metaKey || e.ctrlKey) && e.key === "w") {
1702
- const currentActiveTabId = activeTabIdRef.current;
1703
- const currentTabs = tabsRef.current;
1704
- if (currentActiveTabId && currentTabs.length > 0) {
1705
- e.preventDefault();
1706
- e.stopPropagation();
1707
- closeTabRef.current?.(currentActiveTabId);
1708
- }
1940
+ useTabKeyboardShortcuts({
1941
+ onNewTab: () => {
1942
+ if (isCreatingTabRef.current)
1709
1943
  return;
1944
+ isCreatingTabRef.current = true;
1945
+ addNewTab();
1946
+ setTimeout(() => {
1947
+ isCreatingTabRef.current = false;
1948
+ }, 500);
1949
+ },
1950
+ onCloseTab: () => {
1951
+ if (activeTabId && tabs.length > 0) {
1952
+ closeTab(activeTabId);
1710
1953
  }
1711
- if ((e.metaKey || e.ctrlKey) && e.key >= "1" && e.key <= "9") {
1712
- e.preventDefault();
1713
- const currentTabs = tabsRef.current;
1714
- const keyNum = parseInt(e.key, 10);
1715
- const tabIndex = keyNum === 9 ? currentTabs.length - 1 : keyNum - 1;
1716
- if (tabIndex >= 0 && tabIndex < currentTabs.length) {
1717
- const targetTab = currentTabs[tabIndex];
1718
- if (targetTab) {
1719
- switchTabRef.current?.(targetTab.id);
1720
- }
1721
- }
1954
+ },
1955
+ onSwitchToTab: (index) => {
1956
+ const tabIndex = index === 8 && tabs.length > 9 ? tabs.length - 1 : index;
1957
+ if (tabIndex >= 0 && tabIndex < tabs.length) {
1958
+ switchTab(tabs[tabIndex].id);
1722
1959
  }
1723
- };
1724
- window.addEventListener("keydown", handleKeyDown);
1725
- return () => window.removeEventListener("keydown", handleKeyDown);
1726
- }, []);
1727
- return /* @__PURE__ */ jsxs3("div", {
1960
+ }
1961
+ });
1962
+ const renderTabAccessory = useCallback2((tab) => {
1963
+ if (tab.id !== activeTabId)
1964
+ return null;
1965
+ const scrollPosition = scrollPositions.get(tab.id) ?? defaultScrollPosition;
1966
+ return /* @__PURE__ */ jsx6("button", {
1967
+ onClick: (e) => {
1968
+ e.stopPropagation();
1969
+ handleToggleScrollLock();
1970
+ },
1971
+ style: {
1972
+ display: "flex",
1973
+ alignItems: "center",
1974
+ justifyContent: "center",
1975
+ width: "16px",
1976
+ height: "16px",
1977
+ borderRadius: "3px",
1978
+ border: "none",
1979
+ backgroundColor: "transparent",
1980
+ cursor: "pointer",
1981
+ color: scrollPosition.isScrollLocked ? theme.colors.success : theme.colors.warning,
1982
+ padding: 0
1983
+ },
1984
+ onMouseEnter: (e) => {
1985
+ e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
1986
+ },
1987
+ onMouseLeave: (e) => {
1988
+ e.currentTarget.style.backgroundColor = "transparent";
1989
+ },
1990
+ title: scrollPosition.isScrollLocked ? "Scroll locked" : "Scroll unlocked",
1991
+ children: scrollPosition.isScrollLocked ? /* @__PURE__ */ jsx6(Lock2, {
1992
+ size: 10
1993
+ }) : /* @__PURE__ */ jsx6(Unlock2, {
1994
+ size: 10
1995
+ })
1996
+ });
1997
+ }, [activeTabId, scrollPositions, defaultScrollPosition, handleToggleScrollLock, theme]);
1998
+ return /* @__PURE__ */ jsxs5("div", {
1728
1999
  style: {
1729
2000
  display: "flex",
1730
2001
  flexDirection: "column",
@@ -1732,205 +2003,50 @@ var TabbedTerminalPanelInner = ({
1732
2003
  backgroundColor: theme.colors.background
1733
2004
  },
1734
2005
  children: [
1735
- !hideHeader && /* @__PURE__ */ jsxs3("div", {
2006
+ !hideHeader && /* @__PURE__ */ jsx6("div", {
1736
2007
  ref: headerRef,
1737
- style: {
1738
- display: "flex",
1739
- alignItems: "stretch",
1740
- height: "40px",
1741
- flexShrink: 0,
1742
- boxSizing: "border-box"
1743
- },
1744
- children: [
1745
- /* @__PURE__ */ jsx4("div", {
1746
- style: {
1747
- display: "flex",
1748
- alignItems: "center",
1749
- gap: "4px",
1750
- padding: "0 8px",
1751
- borderRight: `1px solid ${theme.colors.border}`,
1752
- borderBottom: `1px solid ${theme.colors.border}`,
1753
- boxSizing: "border-box"
1754
- },
1755
- children: /* @__PURE__ */ jsx4("button", {
1756
- onClick: () => onShowAllTerminalsChange?.(!showAllTerminals),
1757
- style: {
1758
- display: "flex",
1759
- alignItems: "center",
1760
- justifyContent: "center",
1761
- width: "28px",
1762
- height: "28px",
1763
- border: "none",
1764
- borderRadius: "4px",
1765
- backgroundColor: showAllTerminals ? `${theme.colors.primary}22` : "transparent",
1766
- cursor: "pointer",
1767
- color: showAllTerminals ? theme.colors.primary : theme.colors.textSecondary
1768
- },
1769
- onMouseEnter: (e) => {
1770
- if (!showAllTerminals) {
1771
- e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
1772
- }
1773
- },
1774
- onMouseLeave: (e) => {
1775
- if (!showAllTerminals) {
1776
- e.currentTarget.style.backgroundColor = "transparent";
1777
- }
1778
- },
1779
- title: showAllTerminals ? "Showing all terminals (click to filter by context)" : "Show all terminals",
1780
- children: showAllTerminals ? /* @__PURE__ */ jsx4(Boxes, {
1781
- size: 14
1782
- }) : /* @__PURE__ */ jsx4(Box, {
1783
- size: 14
1784
- })
1785
- })
1786
- }),
1787
- /* @__PURE__ */ jsx4("div", {
1788
- style: {
1789
- display: "flex",
1790
- alignItems: "center",
1791
- flex: 1,
1792
- overflow: "hidden",
1793
- borderBottom: `1px solid ${theme.colors.border}`,
1794
- boxSizing: "border-box"
1795
- },
1796
- children: tabs.map((tab) => /* @__PURE__ */ jsxs3("div", {
1797
- onClick: (e) => {
1798
- e.stopPropagation();
1799
- switchTab(tab.id);
1800
- },
1801
- onMouseEnter: () => setHoveredTabId(tab.id),
1802
- onMouseLeave: () => setHoveredTabId(null),
1803
- style: {
1804
- display: "flex",
1805
- alignItems: "center",
1806
- justifyContent: "center",
1807
- gap: "6px",
1808
- padding: "6px 8px",
1809
- backgroundColor: tab.isActive ? theme.colors.background : theme.colors.backgroundSecondary,
1810
- borderBottom: "none",
1811
- cursor: "pointer",
1812
- fontSize: theme.fontSizes[1],
1813
- fontWeight: tab.isActive ? theme.fontWeights.semibold : theme.fontWeights.body,
1814
- fontFamily: theme.fonts.body,
1815
- color: tab.isActive ? theme.colors.text : theme.colors.textSecondary,
1816
- whiteSpace: "nowrap",
1817
- transition: "all 0.2s",
1818
- flex: 1,
1819
- minWidth: 0,
1820
- height: "100%",
1821
- position: "relative",
1822
- boxSizing: "border-box"
1823
- },
1824
- children: [
1825
- hoveredTabId === tab.id && /* @__PURE__ */ jsx4("button", {
1826
- onClick: (e) => {
1827
- e.stopPropagation();
1828
- closeTab(tab.id);
1829
- },
1830
- style: {
1831
- display: "flex",
1832
- alignItems: "center",
1833
- justifyContent: "center",
1834
- width: "16px",
1835
- height: "16px",
1836
- borderRadius: "3px",
1837
- border: "none",
1838
- backgroundColor: "transparent",
1839
- cursor: "pointer",
1840
- color: theme.colors.textSecondary,
1841
- padding: 0,
1842
- position: "absolute",
1843
- left: "8px"
1844
- },
1845
- onMouseEnter: (e) => {
1846
- e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
1847
- },
1848
- onMouseLeave: (e) => {
1849
- e.currentTarget.style.backgroundColor = "transparent";
1850
- },
1851
- children: /* @__PURE__ */ jsx4(X2, {
1852
- size: 12
1853
- })
1854
- }),
1855
- /* @__PURE__ */ jsx4("span", {
1856
- title: tab.directory,
1857
- children: tab.label
1858
- }),
1859
- tab.isActive && /* @__PURE__ */ jsx4("button", {
1860
- onClick: (e) => {
1861
- e.stopPropagation();
1862
- handleToggleScrollLock();
1863
- },
1864
- style: {
1865
- display: "flex",
1866
- alignItems: "center",
1867
- justifyContent: "center",
1868
- width: "16px",
1869
- height: "16px",
1870
- borderRadius: "3px",
1871
- border: "none",
1872
- backgroundColor: "transparent",
1873
- cursor: "pointer",
1874
- color: (scrollPositions.get(tab.id) ?? defaultScrollPosition).isScrollLocked ? theme.colors.success : theme.colors.warning,
1875
- padding: 0,
1876
- position: "absolute",
1877
- right: "8px"
1878
- },
1879
- onMouseEnter: (e) => {
1880
- e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
1881
- },
1882
- onMouseLeave: (e) => {
1883
- e.currentTarget.style.backgroundColor = "transparent";
1884
- },
1885
- title: (scrollPositions.get(tab.id) ?? defaultScrollPosition).isScrollLocked ? "Scroll locked" : "Scroll unlocked",
1886
- children: (scrollPositions.get(tab.id) ?? defaultScrollPosition).isScrollLocked ? /* @__PURE__ */ jsx4(Lock2, {
1887
- size: 10
1888
- }) : /* @__PURE__ */ jsx4(Unlock2, {
1889
- size: 10
1890
- })
1891
- })
1892
- ]
1893
- }, tab.id))
1894
- }),
1895
- /* @__PURE__ */ jsx4("div", {
2008
+ children: /* @__PURE__ */ jsx6(TabBar, {
2009
+ tabs: genericTabs,
2010
+ activeTabId,
2011
+ onTabClick: switchTab,
2012
+ onTabClose: closeTab,
2013
+ onNewTab: addNewTab,
2014
+ leftSection: /* @__PURE__ */ jsx6("button", {
2015
+ onClick: () => onShowAllTerminalsChange?.(!showAllTerminals),
1896
2016
  style: {
1897
2017
  display: "flex",
1898
2018
  alignItems: "center",
1899
- gap: "4px",
1900
- padding: "0 8px",
1901
- borderLeft: `1px solid ${theme.colors.border}`,
1902
- borderBottom: `1px solid ${theme.colors.border}`,
1903
- boxSizing: "border-box"
2019
+ justifyContent: "center",
2020
+ width: "28px",
2021
+ height: "28px",
2022
+ border: "none",
2023
+ borderRadius: "4px",
2024
+ backgroundColor: showAllTerminals ? `${theme.colors.primary}22` : "transparent",
2025
+ cursor: "pointer",
2026
+ color: showAllTerminals ? theme.colors.primary : theme.colors.textSecondary
1904
2027
  },
1905
- children: /* @__PURE__ */ jsx4("button", {
1906
- onClick: () => addNewTab(),
1907
- style: {
1908
- display: "flex",
1909
- alignItems: "center",
1910
- justifyContent: "center",
1911
- width: "28px",
1912
- height: "28px",
1913
- border: "none",
1914
- borderRadius: "4px",
1915
- backgroundColor: "transparent",
1916
- cursor: "pointer",
1917
- color: theme.colors.textSecondary
1918
- },
1919
- onMouseEnter: (e) => {
2028
+ onMouseEnter: (e) => {
2029
+ if (!showAllTerminals) {
1920
2030
  e.currentTarget.style.backgroundColor = theme.colors.backgroundTertiary;
1921
- },
1922
- onMouseLeave: (e) => {
2031
+ }
2032
+ },
2033
+ onMouseLeave: (e) => {
2034
+ if (!showAllTerminals) {
1923
2035
  e.currentTarget.style.backgroundColor = "transparent";
1924
- },
1925
- title: "New terminal (Cmd+T)",
1926
- children: /* @__PURE__ */ jsx4(Plus, {
1927
- size: 14
1928
- })
2036
+ }
2037
+ },
2038
+ title: showAllTerminals ? "Showing all terminals (click to filter by context)" : "Show all terminals",
2039
+ children: showAllTerminals ? /* @__PURE__ */ jsx6(Boxes, {
2040
+ size: 14
2041
+ }) : /* @__PURE__ */ jsx6(Box, {
2042
+ size: 14
1929
2043
  })
1930
- })
1931
- ]
2044
+ }),
2045
+ renderTabAccessory,
2046
+ showKeyboardHints: false
2047
+ })
1932
2048
  }),
1933
- /* @__PURE__ */ jsxs3("div", {
2049
+ /* @__PURE__ */ jsxs5("div", {
1934
2050
  style: {
1935
2051
  flex: 1,
1936
2052
  display: "flex",
@@ -1940,20 +2056,74 @@ var TabbedTerminalPanelInner = ({
1940
2056
  minHeight: 0
1941
2057
  },
1942
2058
  children: [
1943
- tabs.map((tab) => /* @__PURE__ */ jsx4(TerminalTabContent, {
1944
- ref: getRefCallback(tab.id),
1945
- tab,
1946
- sessionId: sessionIds.get(tab.id) || null,
1947
- isActive: tab.id === activeTabId,
1948
- isVisible,
1949
- actions,
1950
- events,
1951
- terminalContext,
1952
- onSessionCreated: handleSessionCreated,
1953
- onScrollPositionChange: handleTabScrollPositionChange,
1954
- isForeign: tab.id.startsWith("tab-foreign-")
1955
- }, tab.id)),
1956
- tabs.length === 0 && /* @__PURE__ */ jsxs3("div", {
2059
+ tabs.map((tab) => {
2060
+ const isActive = tab.id === activeTabId;
2061
+ const sessionId = sessionIds.get(tab.id) || null;
2062
+ if (renderTabContent) {
2063
+ const customContent = renderTabContent(tab, isActive, sessionId);
2064
+ if (customContent === null && tab.contentType === "terminal") {
2065
+ return /* @__PURE__ */ jsx6(TerminalTabContent, {
2066
+ ref: getRefCallback(tab.id),
2067
+ tab,
2068
+ sessionId,
2069
+ isActive,
2070
+ isVisible,
2071
+ actions,
2072
+ events,
2073
+ terminalContext,
2074
+ onSessionCreated: handleSessionCreated,
2075
+ onScrollPositionChange: handleTabScrollPositionChange,
2076
+ isForeign: tab.id.startsWith("tab-foreign-")
2077
+ }, tab.id);
2078
+ }
2079
+ return /* @__PURE__ */ jsx6("div", {
2080
+ style: {
2081
+ display: isActive ? "flex" : "none",
2082
+ flexDirection: "column",
2083
+ height: "100%",
2084
+ width: "100%"
2085
+ },
2086
+ children: customContent
2087
+ }, tab.id);
2088
+ }
2089
+ if (tab.contentType === "terminal") {
2090
+ return /* @__PURE__ */ jsx6(TerminalTabContent, {
2091
+ ref: getRefCallback(tab.id),
2092
+ tab,
2093
+ sessionId,
2094
+ isActive,
2095
+ isVisible,
2096
+ actions,
2097
+ events,
2098
+ terminalContext,
2099
+ onSessionCreated: handleSessionCreated,
2100
+ onScrollPositionChange: handleTabScrollPositionChange,
2101
+ isForeign: tab.id.startsWith("tab-foreign-")
2102
+ }, tab.id);
2103
+ }
2104
+ return /* @__PURE__ */ jsxs5("div", {
2105
+ style: {
2106
+ display: isActive ? "flex" : "none",
2107
+ alignItems: "center",
2108
+ justifyContent: "center",
2109
+ height: "100%",
2110
+ color: theme.colors.textSecondary
2111
+ },
2112
+ children: [
2113
+ /* @__PURE__ */ jsxs5("p", {
2114
+ children: [
2115
+ "Unknown content type: ",
2116
+ tab.contentType
2117
+ ]
2118
+ }),
2119
+ /* @__PURE__ */ jsx6("p", {
2120
+ style: { fontSize: theme.fontSizes[0], marginTop: "8px" },
2121
+ children: "Provide a renderTabContent prop to render custom tab types"
2122
+ })
2123
+ ]
2124
+ }, tab.id);
2125
+ }),
2126
+ tabs.length === 0 && /* @__PURE__ */ jsxs5("div", {
1957
2127
  style: {
1958
2128
  display: "flex",
1959
2129
  flexDirection: "column",
@@ -1963,14 +2133,14 @@ var TabbedTerminalPanelInner = ({
1963
2133
  color: theme.colors.textSecondary
1964
2134
  },
1965
2135
  children: [
1966
- /* @__PURE__ */ jsx4(TerminalIcon2, {
2136
+ /* @__PURE__ */ jsx6(TerminalIcon2, {
1967
2137
  size: 32,
1968
2138
  style: { opacity: 0.5, marginBottom: "16px" }
1969
2139
  }),
1970
- /* @__PURE__ */ jsx4("p", {
2140
+ /* @__PURE__ */ jsx6("p", {
1971
2141
  children: "No terminal sessions"
1972
2142
  }),
1973
- /* @__PURE__ */ jsx4("button", {
2143
+ /* @__PURE__ */ jsx6("button", {
1974
2144
  onClick: () => addNewTab(),
1975
2145
  style: {
1976
2146
  marginTop: "16px",
@@ -1993,7 +2163,7 @@ var TabbedTerminalPanelInner = ({
1993
2163
  });
1994
2164
  };
1995
2165
  TabbedTerminalPanelInner.displayName = "TabbedTerminalPanelInner";
1996
- var TabbedTerminalPanel = React.memo(TabbedTerminalPanelInner, (prevProps, nextProps) => {
2166
+ var TabbedTerminalPanelMemoized = React2.memo(TabbedTerminalPanelInner, (prevProps, nextProps) => {
1997
2167
  const changes = [];
1998
2168
  if (prevProps.terminalContext !== nextProps.terminalContext)
1999
2169
  changes.push("terminalContext");
@@ -2015,9 +2185,12 @@ var TabbedTerminalPanel = React.memo(TabbedTerminalPanelInner, (prevProps, nextP
2015
2185
  changes.push("onShowAllTerminalsChange");
2016
2186
  if (prevProps.initialTabs !== nextProps.initialTabs)
2017
2187
  changes.push("initialTabs");
2188
+ if (prevProps.renderTabContent !== nextProps.renderTabContent)
2189
+ changes.push("renderTabContent");
2018
2190
  return changes.length === 0;
2019
2191
  });
2020
- TabbedTerminalPanel.displayName = "TabbedTerminalPanel";
2192
+ TabbedTerminalPanelMemoized.displayName = "TabbedTerminalPanel";
2193
+ var TabbedTerminalPanel = TabbedTerminalPanelMemoized;
2021
2194
  // src/tools/index.ts
2022
2195
  var createTerminalSessionTool = {
2023
2196
  name: "create_terminal_session",
@@ -2200,12 +2373,14 @@ var onPackageUnload = async () => {
2200
2373
  export {
2201
2374
  writeToTerminalTool,
2202
2375
  useThemedTerminal,
2376
+ useTabKeyboardShortcuts,
2203
2377
  terminalPanelToolsMetadata,
2204
2378
  terminalPanelTools,
2205
2379
  panels,
2206
2380
  onPackageUnload,
2207
2381
  onPackageLoad,
2208
2382
  isTerminalLoading,
2383
+ isTabOfType,
2209
2384
  getWorkspacePath,
2210
2385
  getTerminalSlice,
2211
2386
  getTerminalSessions,
@@ -2221,5 +2396,7 @@ export {
2221
2396
  ThemedTerminalWithProvider,
2222
2397
  ThemedTerminal,
2223
2398
  TerminalPanel,
2224
- TabbedTerminalPanel
2399
+ TabbedTerminalPanel,
2400
+ TabButton,
2401
+ TabBar
2225
2402
  };