diff --git a/apps/x/apps/renderer/src/App.tsx b/apps/x/apps/renderer/src/App.tsx index b6e6add7..1f5cb153 100644 --- a/apps/x/apps/renderer/src/App.tsx +++ b/apps/x/apps/renderer/src/App.tsx @@ -2111,7 +2111,7 @@ function App() { return next }) - if (event.toolCallId) { + if (event.toolCallId && event.toolName !== 'executeCommand') { setToolOpenForTab(activeChatTabIdRef.current, event.toolCallId, false) } @@ -4361,7 +4361,7 @@ function App() { state={toToolState(item.status)} /> - {item.streamingOutput && item.status === 'running' ? ( + {item.streamingOutput ? ( diff --git a/apps/x/apps/renderer/src/components/chat-sidebar.tsx b/apps/x/apps/renderer/src/components/chat-sidebar.tsx index 6fa295b1..a7551757 100644 --- a/apps/x/apps/renderer/src/components/chat-sidebar.tsx +++ b/apps/x/apps/renderer/src/components/chat-sidebar.tsx @@ -20,6 +20,7 @@ import { Tool, ToolContent, ToolGroupComponent, ToolHeader, ToolTabbedContent } import { WebSearchResult } from '@/components/ai-elements/web-search-result' import { ComposioConnectCard } from '@/components/ai-elements/composio-connect-card' import { PermissionRequest } from '@/components/ai-elements/permission-request' +import { TerminalOutput } from '@/components/terminal-output' import { AskHumanRequest } from '@/components/ai-elements/ask-human-request' import { Suggestions } from '@/components/ai-elements/suggestions' import { type PromptInputMessage, type FileMention } from '@/components/ai-elements/prompt-input' @@ -59,6 +60,31 @@ const streamdownComponents = { pre: MarkdownPreOverride } // into
so typed line breaks are preserved without requiring blank lines. const userMessageRemarkPlugins = [...Object.values(defaultRemarkPlugins), remarkBreaks] +function AutoScrollPre({ className, children }: { className?: string; children: React.ReactNode }) { + const ref = useRef(null) + const stickToBottom = useRef(true) + + useEffect(() => { + const el = ref.current + if (el && stickToBottom.current) { + el.scrollTop = el.scrollHeight + } + }, [children]) + + const handleScroll = useCallback(() => { + const el = ref.current + if (!el) return + const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 24 + stickToBottom.current = atBottom + }, []) + + return ( +
+      {children}
+    
+ ) +} + /* ─── Billing error helpers ─── */ const BILLING_ERROR_PATTERNS = [ @@ -452,7 +478,13 @@ export function ChatSidebar({ > - + {item.streamingOutput ? ( + + + + ) : ( + + )} )