+ {/* Gauge width: w-24 (96px) normally, w-16 (64px) when narrow */}
+
void;
}
-export const RightPanel = forwardRef(function RightPanel(props, ref) {
+export const RightPanel = memo(forwardRef(function RightPanel(props, ref) {
const {
session, theme, shortcuts, rightPanelOpen, setRightPanelOpen, rightPanelWidth,
setRightPanelWidthState, activeRightTab, setActiveRightTab, activeFocus, setActiveFocus,
@@ -560,4 +560,4 @@ export const RightPanel = forwardRef(function
)}
);
-});
+}));
diff --git a/src/renderer/components/SessionList.tsx b/src/renderer/components/SessionList.tsx
index 6b23101f..8e57fed3 100644
--- a/src/renderer/components/SessionList.tsx
+++ b/src/renderer/components/SessionList.tsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useRef } from 'react';
+import React, { useState, useEffect, useRef, memo } from 'react';
import {
Wand2, Plus, Settings, ChevronRight, ChevronDown, ChevronUp, X, Keyboard,
Radio, Copy, ExternalLink, PanelLeftClose, PanelLeftOpen, Folder, Info, GitBranch, Bot, Clock,
@@ -751,7 +751,7 @@ interface SessionListProps {
allGroupChatParticipantStates?: Map
>;
}
-export function SessionList(props: SessionListProps) {
+function SessionListInner(props: SessionListProps) {
const {
theme, sessions, groups, sortedSessions, activeSessionId, leftSidebarOpen,
leftSidebarWidthState, activeFocus, selectedSidebarIndex, editingGroupId,
@@ -2167,3 +2167,5 @@ export function SessionList(props: SessionListProps) {
);
}
+
+export const SessionList = memo(SessionListInner);
diff --git a/src/renderer/components/TabBar.tsx b/src/renderer/components/TabBar.tsx
index 1b1a6c51..a20d9c7d 100644
--- a/src/renderer/components/TabBar.tsx
+++ b/src/renderer/components/TabBar.tsx
@@ -1,6 +1,6 @@
-import React, { useState, useRef, useCallback, useEffect } from 'react';
+import React, { useState, useRef, useCallback, useEffect, memo } from 'react';
import { createPortal } from 'react-dom';
-import { X, Plus, Star, Copy, Edit2, Mail, Pencil, Search, GitMerge, ArrowRightCircle, Minimize2 } from 'lucide-react';
+import { X, Plus, Star, Copy, Edit2, Mail, Pencil, Search, GitMerge, ArrowRightCircle, Minimize2, Download, Clipboard, Minus, ArrowLeftToLine, ArrowRightToLine } from 'lucide-react';
import type { AITab, Theme } from '../types';
import { hasDraft } from '../utils/tabHelpers';
@@ -275,6 +275,18 @@ function Tab({
setOverlayOpen(false);
};
+ const handleCopyContextClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ onCopyContext?.();
+ setOverlayOpen(false);
+ };
+
+ const handleExportHtmlClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ onExportHtml?.();
+ setOverlayOpen(false);
+ };
+
const displayName = getTabDisplayName(tab);
// Browser-style tab: all tabs have borders, active tab "connects" to content
@@ -587,7 +599,7 @@ function Tab({
style={{ color: theme.colors.textMain }}
disabled={hasOnlyOneTab}
>
-
+
Close Others
@@ -600,7 +612,7 @@ function Tab({
style={{ color: theme.colors.textMain }}
disabled={isFirstTab}
>
-
+
Close Tabs to the Left
@@ -613,7 +625,7 @@ function Tab({
style={{ color: theme.colors.textMain }}
disabled={isLastTab}
>
-
+
Close Tabs to the Right
@@ -629,7 +641,7 @@ function Tab({
* Shows tabs for each Claude Code conversation within a Maestro session.
* Appears only in AI mode (hidden in terminal mode).
*/
-export function TabBar({
+function TabBarInner({
tabs,
activeTabId,
theme,
@@ -931,3 +943,5 @@ export function TabBar({