From 6aab4f7d2a345ed1905c163363fe49ea1da42040 Mon Sep 17 00:00:00 2001 From: indifferentketchup Date: Wed, 20 May 2026 18:13:55 +0000 Subject: [PATCH] ChatTabBar: + button dropdown to add chat / terminal / agent pane Replaces single onNewChat handler with onAddPane(kind). Terminal pane header gets matching + dropdown. Context menu "New chat" stays. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/src/components/ChatTabBar.tsx | 46 ++++++++++++++++++-------- apps/web/src/components/Workspace.tsx | 33 ++++++++++++++++-- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/apps/web/src/components/ChatTabBar.tsx b/apps/web/src/components/ChatTabBar.tsx index 0237c74..91111e9 100644 --- a/apps/web/src/components/ChatTabBar.tsx +++ b/apps/web/src/components/ChatTabBar.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { History, MessageSquare, Plus, X } from 'lucide-react'; +import { Bot, History, MessageSquare, Plus, Terminal, X } from 'lucide-react'; import type { Chat, WorkspacePane } from '@/api/types'; import { StatusDot } from '@/components/StatusDot'; import { @@ -9,6 +9,12 @@ import { ContextMenuSeparator, ContextMenuTrigger, } from '@/components/ui/context-menu'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; import { useLongPress } from '@/hooks/useLongPress'; import { cn } from '@/lib/utils'; @@ -20,7 +26,7 @@ interface Props { onCloseOthers: (chatId: string) => void; onCloseToRight: (chatId: string) => void; onCloseAll: () => void; - onNewChat: () => void; + onAddPane: (kind: 'chat' | 'terminal' | 'agent') => void; onShowHistory: () => void; onRename: (chatId: string, name: string) => Promise; onRemovePane?: () => void; @@ -34,7 +40,7 @@ export function ChatTabBar({ onCloseOthers, onCloseToRight, onCloseAll, - onNewChat, + onAddPane, onShowHistory, onRename, onRemovePane, @@ -125,7 +131,7 @@ export function ChatTabBar({ - onNewChat()}> + onAddPane('chat')}> New chat @@ -164,15 +170,29 @@ export function ChatTabBar({ )}
- + + + + + + onAddPane('chat')}> + New chat + + onAddPane('terminal')}> + New terminal + + onAddPane('agent')}> + New agent + + + + + + addSplitPane('chat')}> + New chat + + addSplitPane('terminal')}> + New terminal + + addSplitPane('agent')}> + New agent + + + {/* v1.10.4: iOS Safari restricts navigator.clipboard.readText outside direct user gestures. A real button click IS a gesture, so this works where keystroke-driven paste may @@ -250,7 +277,7 @@ export function Workspace({ e.stopPropagation(); terminalsRegistry.get(pane.id)?.paste(); }} - className="ml-auto inline-flex items-center justify-center size-5 rounded text-muted-foreground hover:bg-muted hover:text-foreground max-md:size-7" + className="inline-flex items-center justify-center size-5 rounded text-muted-foreground hover:bg-muted hover:text-foreground max-md:size-7" aria-label="Paste from clipboard" title="Paste from clipboard" >