@@ -27,6 +27,7 @@ interface Session {
2727 config : SessionConfig ;
2828 worktreePath : string ;
2929 hasActivePty : boolean ;
30+ hasUnreadActivity : boolean ;
3031}
3132
3233interface McpServer {
@@ -73,6 +74,15 @@ function createTerminalUI(sessionId: string) {
7374 ipcRenderer . send ( "session-input" , sessionId , data ) ;
7475 } ) ;
7576
77+ // Listen for bell character to mark unread activity
78+ term . onBell ( ( ) => {
79+ console . log ( `Bell received for session ${ sessionId } , activeSessionId: ${ activeSessionId } ` ) ;
80+ if ( activeSessionId !== sessionId ) {
81+ console . log ( `Marking session ${ sessionId } as unread` ) ;
82+ markSessionAsUnread ( sessionId ) ;
83+ }
84+ } ) ;
85+
7686 // Handle resize
7787 const resizeHandler = ( ) => {
7888 if ( activeSessionId === sessionId ) {
@@ -95,6 +105,7 @@ function addSession(persistedSession: PersistedSession, hasActivePty: boolean) {
95105 config : persistedSession . config ,
96106 worktreePath : persistedSession . worktreePath ,
97107 hasActivePty,
108+ hasUnreadActivity : false ,
98109 } ;
99110
100111 sessions . set ( persistedSession . id , session ) ;
@@ -299,6 +310,32 @@ function addTab(sessionId: string, name: string) {
299310 tabsContainer . appendChild ( tab ) ;
300311}
301312
313+ function markSessionAsUnread ( sessionId : string ) {
314+ const session = sessions . get ( sessionId ) ;
315+ if ( ! session ) return ;
316+
317+ session . hasUnreadActivity = true ;
318+
319+ // Add unread indicator to tab
320+ const tab = document . getElementById ( `tab-${ sessionId } ` ) ;
321+ if ( tab && ! tab . classList . contains ( "unread" ) ) {
322+ tab . classList . add ( "unread" ) ;
323+ }
324+ }
325+
326+ function clearUnreadStatus ( sessionId : string ) {
327+ const session = sessions . get ( sessionId ) ;
328+ if ( ! session ) return ;
329+
330+ session . hasUnreadActivity = false ;
331+
332+ // Remove unread indicator from tab
333+ const tab = document . getElementById ( `tab-${ sessionId } ` ) ;
334+ if ( tab ) {
335+ tab . classList . remove ( "unread" ) ;
336+ }
337+ }
338+
302339function switchToSession ( sessionId : string ) {
303340 // Hide all sessions
304341 sessions . forEach ( ( session , id ) => {
@@ -317,6 +354,9 @@ function switchToSession(sessionId: string) {
317354 document . getElementById ( `sidebar-${ sessionId } ` ) ?. classList . add ( "active" ) ;
318355 activeSessionId = sessionId ;
319356
357+ // Clear unread status when switching to this session
358+ clearUnreadStatus ( sessionId ) ;
359+
320360 // Focus and resize
321361 session . terminal . focus ( ) ;
322362 setTimeout ( ( ) => {
@@ -407,6 +447,11 @@ ipcRenderer.on("session-output", (_event, sessionId: string, data: string) => {
407447 const session = sessions . get ( sessionId ) ;
408448 if ( session && session . terminal ) {
409449 session . terminal . write ( data ) ;
450+
451+ // Mark as unread if this is not the active session and there's output
452+ if ( activeSessionId !== sessionId && session . hasActivePty ) {
453+ markSessionAsUnread ( sessionId ) ;
454+ }
410455 }
411456} ) ;
412457
0 commit comments