diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index a982c1fc6e85868b132d93e392cc640433b485d9..41c7ff36fc482abec692acf944ed13e9ee998623 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -27,6 +27,16 @@ function EventRouter() { }); }, [api, dispatch]); + useEffect(() => { + if (!api) return; + return api.terminal.onEvent((event) => { + dispatch({ + type: "APPLY_TERMINAL_EVENT", + event, + }); + }); + }, [api, dispatch]); + return null; } @@ -82,6 +92,7 @@ function AutoProjectBootstrap() { terminalOpen: false, terminalHeight: DEFAULT_THREAD_TERMINAL_HEIGHT, terminalIds: [DEFAULT_THREAD_TERMINAL_ID], + runningTerminalIds: [], activeTerminalId: DEFAULT_THREAD_TERMINAL_ID, terminalGroups: [ { diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index 32a832a491a6160dcb9b219cc52c49af6be1de61..858e438b503086b1afa14af6f663178dc714cf60 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -32,7 +32,7 @@ function inferProjectName(cwd: string): string { } interface ThreadStatusPill { - label: "Working" | "Connecting" | "Completed" | "Awaiting response"; + label: "Working" | "Connecting" | "Completed" | "Awaiting response" | "Terminal"; colorClass: string; dotClass: string; pulse: boolean; @@ -89,6 +89,18 @@ function threadStatusPill(thread: Thread, hasPendingApprovals: boolean): ThreadS return null; } +function terminalStatusPill(thread: Thread): ThreadStatusPill | null { + if (thread.runningTerminalIds.length === 0) { + return null; + } + return { + label: "Terminal", + colorClass: "text-teal-600 dark:text-teal-300/90", + dotClass: "bg-teal-500 dark:bg-teal-300/90", + pulse: true, + }; +} + export default function Sidebar() { const { state, dispatch } = useStore(); const api = useNativeApi(); @@ -118,6 +130,7 @@ export default function Sidebar() { terminalOpen: false, terminalHeight: DEFAULT_THREAD_TERMINAL_HEIGHT, terminalIds: [DEFAULT_THREAD_TERMINAL_ID], + runningTerminalIds: [], activeTerminalId: DEFAULT_THREAD_TERMINAL_ID, terminalGroups: [ { @@ -388,6 +401,7 @@ export default function Sidebar() { thread, pendingApprovalByThreadId.get(thread.id) === true, ); + const terminalStatus = terminalStatusPill(thread); return (