import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import '@xterm/xterm/css/xterm.css';
import type { Project, ProjectSession } from '../../../types/app';
import { SHELL_RESTART_DELAY_MS } from '../constants/constants';
import { useShellRuntime } from '../hooks/useShellRuntime';
import { getSessionDisplayName } from '../utils/auth';
import ShellConnectionOverlay from './subcomponents/ShellConnectionOverlay';
import ShellEmptyState from './subcomponents/ShellEmptyState';
import ShellHeader from './subcomponents/ShellHeader';
import ShellMinimalView from './subcomponents/ShellMinimalView';
import TerminalShortcutsPanel from './subcomponents/TerminalShortcutsPanel';
type ShellProps = {
selectedProject?: Project | null;
selectedSession?: ProjectSession | null;
initialCommand?: string | null;
isPlainShell?: boolean;
onProcessComplete?: ((exitCode: number) => void) | null;
minimal?: boolean;
autoConnect?: boolean;
isActive?: boolean;
};
export default function Shell({
selectedProject = null,
selectedSession = null,
initialCommand = null,
isPlainShell = false,
onProcessComplete = null,
minimal = false,
autoConnect = false,
isActive,
}: ShellProps) {
const { t } = useTranslation('chat');
const [isRestarting, setIsRestarting] = useState(false);
// Keep the public API stable for existing callers that still pass `isActive`.
void isActive;
const {
terminalContainerRef,
terminalRef,
wsRef,
isConnected,
isInitialized,
isConnecting,
authUrl,
authUrlVersion,
connectToShell,
disconnectFromShell,
openAuthUrlInBrowser,
copyAuthUrlToClipboard,
} = useShellRuntime({
selectedProject,
selectedSession,
initialCommand,
isPlainShell,
minimal,
autoConnect,
isRestarting,
onProcessComplete,
});
const sessionDisplayName = useMemo(() => getSessionDisplayName(selectedSession), [selectedSession]);
const sessionDisplayNameShort = useMemo(
() => (sessionDisplayName ? sessionDisplayName.slice(0, 30) : null),
[sessionDisplayName],
);
const sessionDisplayNameLong = useMemo(
() => (sessionDisplayName ? sessionDisplayName.slice(0, 50) : null),
[sessionDisplayName],
);
const handleRestartShell = useCallback(() => {
setIsRestarting(true);
window.setTimeout(() => {
setIsRestarting(false);
}, SHELL_RESTART_DELAY_MS);
}, []);
if (!selectedProject) {
return (