1- import { memo , useEffect , useRef , useState } from "react"
1+ import { memo , useEffect , useRef , useState , useMemo } from "react"
22import { useTranslation } from "react-i18next"
33import { useCloudUpsell } from "@src/hooks/useCloudUpsell"
44import { CloudUpsellDialog } from "@src/components/cloud/CloudUpsellDialog"
55import DismissibleUpsell from "@src/components/common/DismissibleUpsell"
6- import { FoldVertical , ChevronUp , ChevronDown } from "lucide-react"
6+ import { FoldVertical , ChevronUp , ChevronDown , Globe } from "lucide-react"
77import prettyBytes from "pretty-bytes"
88
99import type { ClineMessage } from "@roo-code/types"
@@ -13,9 +13,10 @@ import { findLastIndex } from "@roo/array"
1313
1414import { formatLargeNumber } from "@src/utils/format"
1515import { cn } from "@src/lib/utils"
16- import { StandardTooltip } from "@src/components/ui"
16+ import { StandardTooltip , Button } from "@src/components/ui"
1717import { useExtensionState } from "@src/context/ExtensionStateContext"
1818import { useSelectedModel } from "@/components/ui/hooks/useSelectedModel"
19+ import { vscode } from "@src/utils/vscode"
1920
2021import Thumbnails from "../common/Thumbnails"
2122
@@ -50,7 +51,7 @@ const TaskHeader = ({
5051 todos,
5152} : TaskHeaderProps ) => {
5253 const { t } = useTranslation ( )
53- const { apiConfiguration, currentTaskItem, clineMessages } = useExtensionState ( )
54+ const { apiConfiguration, currentTaskItem, clineMessages, isBrowserSessionActive } = useExtensionState ( )
5455 const { id : modelId , info : model } = useSelectedModel ( apiConfiguration )
5556 const [ isTaskExpanded , setIsTaskExpanded ] = useState ( false )
5657 const [ showLongRunningTaskMessage , setShowLongRunningTaskMessage ] = useState ( false )
@@ -86,6 +87,21 @@ const TaskHeader = ({
8687 const textRef = useRef < HTMLDivElement > ( null )
8788 const contextWindow = model ?. contextWindow || 1
8889
90+ // Detect if this task had any browser session activity so we can show a grey globe when inactive
91+ const browserSessionStartIndex = useMemo ( ( ) => {
92+ const msgs = clineMessages || [ ]
93+ for ( let i = 0 ; i < msgs . length ; i ++ ) {
94+ const m = msgs [ i ] as any
95+ if ( m ?. ask === "browser_action_launch" ) return i
96+ if ( m ?. say === "browser_session_status" && typeof m . text === "string" && m . text . includes ( "opened" ) ) {
97+ return i
98+ }
99+ }
100+ return - 1
101+ } , [ clineMessages ] )
102+
103+ const showBrowserGlobe = browserSessionStartIndex !== - 1 || ! ! isBrowserSessionActive
104+
89105 const condenseButton = (
90106 < StandardTooltip content = { t ( "chat:task.condenseContext" ) } >
91107 < button
@@ -325,6 +341,40 @@ const TaskHeader = ({
325341 </ div >
326342 </ >
327343 ) }
344+ { /* Browser session status moved from bottom bar to header (bottom-right) */ }
345+ { showBrowserGlobe && (
346+ < div
347+ className = "absolute bottom-2 right-3 flex items-center gap-1"
348+ onClick = { ( e ) => e . stopPropagation ( ) } >
349+ < StandardTooltip content = { t ( "chat:browser.session" ) } >
350+ < Button
351+ variant = "ghost"
352+ size = "sm"
353+ aria-label = { t ( "chat:browser.session" ) }
354+ onClick = { ( ) => vscode . postMessage ( { type : "openBrowserSessionPanel" } as any ) }
355+ className = { cn (
356+ "relative h-5 w-5 p-0" ,
357+ "text-vscode-foreground opacity-85" ,
358+ "hover:opacity-100 hover:bg-[rgba(255,255,255,0.03)]" ,
359+ "focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder" ,
360+ ) } >
361+ < Globe
362+ className = "w-4 h-4"
363+ style = { {
364+ color : isBrowserSessionActive
365+ ? "#4ade80"
366+ : "var(--vscode-descriptionForeground)" ,
367+ } }
368+ />
369+ </ Button >
370+ </ StandardTooltip >
371+ { isBrowserSessionActive && (
372+ < span className = "text-sm font-medium" style = { { color : "var(--vscode-testing-iconPassed)" } } >
373+ Active
374+ </ span >
375+ ) }
376+ </ div >
377+ ) }
328378 </ div >
329379 < TodoListDisplay todos = { todos ?? ( task as any ) ?. tool ?. todos ?? [ ] } />
330380 < CloudUpsellDialog open = { isOpen } onOpenChange = { closeUpsell } onConnect = { handleConnect } />
0 commit comments