@@ -30,6 +30,7 @@ export function ChatInput({ isConnected, isProcessing }: ChatInputProps) {
3030 const [ showTabSelector , setShowTabSelector ] = useState ( false )
3131 const [ showSlashPalette , setShowSlashPalette ] = useState ( false )
3232 const textareaRef = useRef < HTMLTextAreaElement > ( null )
33+ const chatModeInitializedRef = useRef < boolean > ( false )
3334 const [ providerOk , setProviderOk ] = useState < boolean > ( true )
3435 const [ historyIndex , setHistoryIndex ] = useState < number > ( - 1 )
3536 const [ draftBeforeHistory , setDraftBeforeHistory ] = useState < string > ( '' )
@@ -38,7 +39,7 @@ export function ChatInput({ isConnected, isProcessing }: ChatInputProps) {
3839 const messages = useChatStore ( state => state . messages )
3940 const { chatMode } = useSettingsStore ( )
4041 const { sendMessage, addMessageListener, removeMessageListener, connected : portConnected } = useSidePanelPortMessaging ( )
41- const { getContextTabs, toggleTabSelection, clearSelectedTabs } = useTabsStore ( )
42+ const { getContextTabs, toggleTabSelection, clearSelectedTabs, fetchOpenTabs } = useTabsStore ( )
4243 const { agents, loadAgents } = useAgentsStore ( )
4344
4445 // Load agents from Chrome storage on mount
@@ -102,15 +103,65 @@ export function ChatInput({ isConnected, isProcessing }: ChatInputProps) {
102103 setInput ( e . detail )
103104 textareaRef . current ?. focus ( )
104105 }
105-
106+
106107 window . addEventListener ( 'setInputValue' , handleSetInput as EventListener )
107108 return ( ) => {
108109 window . removeEventListener ( 'setInputValue' , handleSetInput as EventListener )
109110 }
110111 } , [ ] )
111-
112112
113-
113+ // Fetch tabs on mount to ensure currentTabId is set
114+ useEffect ( ( ) => {
115+ fetchOpenTabs ( undefined , true )
116+ } , [ fetchOpenTabs ] )
117+
118+ // Auto-select current tab when entering chat mode
119+ useEffect ( ( ) => {
120+ if ( chatMode && ! chatModeInitializedRef . current ) {
121+ chatModeInitializedRef . current = true
122+ fetchOpenTabs ( undefined , true )
123+
124+ const timer = setTimeout ( ( ) => {
125+ const state = useTabsStore . getState ( )
126+ // Only auto-select if current tab hasn't been explicitly removed
127+ if ( state . currentTabId !== null && ! state . selectedTabs . includes ( state . currentTabId ) && ! state . isCurrentTabRemoved ) {
128+ toggleTabSelection ( state . currentTabId )
129+ }
130+ } , 150 )
131+
132+ return ( ) => clearTimeout ( timer )
133+ } else if ( ! chatMode ) {
134+ chatModeInitializedRef . current = false
135+ // Clear selections when exiting chat mode
136+ clearSelectedTabs ( )
137+ }
138+ } , [ chatMode , fetchOpenTabs , toggleTabSelection , clearSelectedTabs ] )
139+
140+ // Auto-select new tab when user switches tabs in chat mode
141+ useEffect ( ( ) => {
142+ if ( ! chatMode ) return
143+
144+ const handleTabActivated = ( activeInfo : chrome . tabs . TabActiveInfo ) => {
145+ fetchOpenTabs ( undefined , true )
146+
147+ setTimeout ( ( ) => {
148+ const state = useTabsStore . getState ( )
149+ const newCurrentTabId = state . currentTabId
150+ const currentSelectedTabs = state . selectedTabs
151+ const isCurrentTabRemoved = state . isCurrentTabRemoved
152+
153+ // Only auto-select if current tab hasn't been explicitly removed by user
154+ if ( newCurrentTabId !== null && ! currentSelectedTabs . includes ( newCurrentTabId ) && ! isCurrentTabRemoved ) {
155+ toggleTabSelection ( newCurrentTabId )
156+ }
157+ } , 150 )
158+ }
159+
160+ chrome . tabs . onActivated . addListener ( handleTabActivated )
161+ return ( ) => chrome . tabs . onActivated . removeListener ( handleTabActivated )
162+ } , [ chatMode , fetchOpenTabs , toggleTabSelection ] )
163+
164+
114165 const submitTask = ( query : string ) => {
115166 if ( ! query . trim ( ) ) return
116167
@@ -127,7 +178,11 @@ export function ChatInput({ isConnected, isProcessing }: ChatInputProps) {
127178
128179 // Get selected tab IDs from tabsStore
129180 const contextTabs = getContextTabs ( )
130- const tabIds = contextTabs . length > 0 ? contextTabs . map ( tab => tab . id ) : undefined
181+ // In chat mode, if no tabs are selected, explicitly send null to prevent using current page
182+ // In agent mode, undefined means "use current active tab"
183+ const tabIds = contextTabs . length > 0
184+ ? contextTabs . map ( tab => tab . id )
185+ : ( chatMode ? null : undefined )
131186
132187 // Send to background
133188 setProcessing ( true )
@@ -138,11 +193,16 @@ export function ChatInput({ isConnected, isProcessing }: ChatInputProps) {
138193 chatMode // Include chat mode setting
139194 } )
140195
141- // Clear input and selected tabs
196+ // Clear input and history
142197 setInput ( '' )
143198 setHistoryIndex ( - 1 )
144199 setDraftBeforeHistory ( '' )
145- clearSelectedTabs ( )
200+
201+ // Only clear selected tabs in agent mode (not in chat mode)
202+ if ( ! chatMode ) {
203+ clearSelectedTabs ( )
204+ }
205+
146206 setShowTabSelector ( false )
147207 }
148208
@@ -298,8 +358,8 @@ export function ChatInput({ isConnected, isProcessing }: ChatInputProps) {
298358 </Button>
299359 </div> */ }
300360
301- { /* Selected tabs chips */ }
302- { selectedContextTabs . length > 0 && (
361+ { /* Selected tabs chips - only show in chat mode */ }
362+ { chatMode && selectedContextTabs . length > 0 && (
303363 < div className = "px-2 mb-1" >
304364 < div className = "flex items-center gap-2 overflow-x-auto no-scrollbar py-1" >
305365 { selectedContextTabs . map ( tab => (
@@ -320,7 +380,7 @@ export function ChatInput({ isConnected, isProcessing }: ChatInputProps) {
320380 </ span >
321381 < button
322382 type = "button"
323- className = "ml-1 inline-flex items-center justify-center w-4 h-4 rounded-full hover:bg-foreground/10 text-xs text-muted-foreground hover:text-foreground"
383+ className = "ml-1 inline-flex items-center justify-center w-5 h-5 rounded-full hover:bg-foreground/10 text-sm text-muted-foreground hover:text-foreground"
324384 aria-label = { `Remove ${ tab . title } from selection` }
325385 onClick = { ( ) => handleRemoveSelectedTab ( tab . id ) }
326386 >
0 commit comments