@@ -178,31 +178,81 @@ def get_stats(self) -> EngineStats:
178178 """Return diagnostic statistics for the engine."""
179179 return self ._protocol .get_stats (restarts = self ._restarts )
180180
181- def filter_attached_sessions (self , sessions : list [Session ]) -> list [Session ]:
181+ def filter_attached_sessions (
182+ self ,
183+ sessions : list [Session ],
184+ * ,
185+ server_args : tuple [str | int , ...] | None = None ,
186+ ) -> list [Session ]:
182187 """Hide sessions that are only attached via the control-mode client."""
183188 if self .process is None or self .process .pid is None :
184189 return sessions
185190
186191 ctrl_pid = str (self .process .pid )
187-
188- proc = self .run ("list-clients" , cmd_args = ("-F#{client_pid} #{session_name}" ,))
189- pid_map : dict [str , list [str ]] = {}
192+ effective_server_args = server_args or self ._server_args or ()
193+
194+ proc = self .run (
195+ "list-clients" ,
196+ cmd_args = (
197+ "-F" ,
198+ "#{client_pid} #{client_flags} #{session_name}" ,
199+ ),
200+ server_args = effective_server_args ,
201+ )
202+ pid_map : dict [str , list [tuple [str , str ]]] = {}
190203 for line in proc .stdout :
191204 parts = line .split ()
192- if len (parts ) >= 2 :
193- pid , sess_name = parts [0 ], parts [1 ]
194- pid_map .setdefault (sess_name , []).append (pid )
205+ if len (parts ) >= 3 :
206+ pid , flags , sess_name = parts [0 ], parts [1 ], parts [ 2 ]
207+ pid_map .setdefault (sess_name , []).append (( pid , flags ) )
195208
196209 filtered : list [Session ] = []
197210 for sess_obj in sessions :
198- pids = pid_map .get (sess_obj .session_name or "" , [])
199- # If the only attached client is the control client, hide it.
200- if len (pids ) == 1 and ctrl_pid in pids :
211+ sess_name = sess_obj .session_name or ""
212+
213+ # Never expose the internal control session we create to hold the
214+ # control client when attach_to is unset.
215+ if not self ._attach_to and sess_name == self ._session_name :
201216 continue
202- filtered .append (sess_obj )
217+
218+ clients = pid_map .get (sess_name , [])
219+ non_control_clients = [
220+ (pid , flags )
221+ for pid , flags in clients
222+ if "C" not in flags and pid != ctrl_pid
223+ ]
224+
225+ if non_control_clients :
226+ filtered .append (sess_obj )
203227
204228 return filtered
205229
230+ def can_switch_client (
231+ self ,
232+ * ,
233+ server_args : tuple [str | int , ...] | None = None ,
234+ ) -> bool :
235+ """Return True if there is at least one non-control client attached."""
236+ if self .process is None or self .process .pid is None :
237+ return False
238+
239+ ctrl_pid = str (self .process .pid )
240+ effective_server_args = server_args or self ._server_args or ()
241+
242+ proc = self .run (
243+ "list-clients" ,
244+ cmd_args = ("-F" , "#{client_pid} #{client_flags}" ),
245+ server_args = effective_server_args ,
246+ )
247+ for line in proc .stdout :
248+ parts = line .split ()
249+ if len (parts ) >= 2 :
250+ pid , flags = parts [0 ], parts [1 ]
251+ if "C" not in flags and pid != ctrl_pid :
252+ return True
253+
254+ return False
255+
206256 # Internals ---------------------------------------------------------
207257 def _ensure_process (self , server_args : tuple [str | int , ...]) -> None :
208258 if self .process is None :
0 commit comments