
    ui                     X    d Z ddlZddlmZ ddlmZmZ ddlmZm	Z	  G d d          Z
dS )u   Tmux 会话封装器。    N)Path)FinalOptional)PtyStateSessionModec            	          e Zd ZU dZ eg d          Zeee                  ed<   i ddddddddddd	d	d
d
ddddddddddddddddddddZ	ee
eef                  ed<   d2defdZd3dededefdZdedefd Zdedd!fd"Zd3dededefd#Zd4ded%ed&edd!fd'Zded(edd!fd)Zd5ded,ed-edefd.Zdedee         fd/Zdedefd0Zdedefd1Zd!S )6TmuxWrapperu1   tmux 会话封装器，处理底层 PTY 交互。)vimnvimvitophtopbtoplessmoremanclaudeaiderpythonnodeirbipythonINTERACTIVE_PROCESSESzC-czC-dzC-zzC-azC-ezC-uzC-kzC-wzC-rEscEscapeTabUpDownLeftRightEnterSpaceSPECIAL_KEYSbutler_session_prefixc                     || _         d S )N)r%   )selfr%   s     5/root/projects/qq-shell/src/butler/session/wrapper.py__init__zTmuxWrapper.__init__   s    ,       user_idseqreturnc                 |    | j          | }|dk    r| j          | d| }t          j        dddd|gdd           |S )	u%   为用户创建独立 tmux session。r+   _tmuxznew-sessionz-dz-sT)checkcapture_output)r%   
subprocessrunr'   r,   r-   session_names       r(   create_sessionzTmuxWrapper.create_session!   sn    -8w8877"1B7BBSBBL]D$=	
 	
 	
 	

 r*   r7   c                 L    t          j        ddd|gd          }|j        dk    S )u   检查 session 是否存在。r1   zhas-session-tTr3   r   )r4   r5   
returncode)r'   r7   results      r(   session_existszTmuxWrapper.session_exists-   s7    ]D,7
 
 
  A%%r*   Nc                 :    t          j        ddd|gd           dS )u   销毁 session。r1   zkill-sessionr:   Tr;   Nr4   r5   )r'   r7   s     r(   kill_sessionzTmuxWrapper.kill_session5   s4    ^T<8	
 	
 	
 	
 	
 	
r*   c                     | j          | }|dk    r| j          | d| }|                     |          s|                     ||          S |S )u    获取或创建用户 session。r+   r0   )r%   r>   r8   r6   s       r(   get_or_create_sessionz!TmuxWrapper.get_or_create_session<   sk    -8w8877"1B7BBSBBL""<00 	5&&w444r*   Tkeysenterc                     || j         v r*| j         |         }t          j        ddd||gd           dS t          j        dddd||gd           |rt          j        ddd|dgd           dS dS )	u   向 session 发送按键。r1   	send-keysr:   Tr;   -lr!   N)r#   r4   r5   )r'   r7   rD   rE   tmux_keys        r(   	send_keyszTmuxWrapper.send_keysE   s    4$$$(.HNdL(C#     
 NdD,E#     [$gF#'      r*   datac                 >    t          j        dddd||gd           dS )u'   发送原始数据（不含 Enter）。r1   rG   rH   r:   Tr;   Nr@   )r'   r7   rK   s      r(   send_rawzTmuxWrapper.send_rawX   s8    [$lDA	
 	
 	
 	
 	
 	
r*   Fas_ansi
start_linec           	          ddd|ddt          |          g}|r|                    d           t          j        |dd          }|j        S )	u   抓取终端屏幕内容。r1   zcapture-paner:   z-pz-Sz-eTr3   text)strappendr4   r5   stdout)r'   r7   rO   rP   cmdr=   s         r(   capture_panezTmuxWrapper.capture_pane_   s]     N,#j//	
  	JJtDtDDD}r*   c                    t          j        ddd|ddgdd          }|j                                                            d          }|r|d	         sd
S |d	         }	 t          j        dd|dddgdd          }|j                                                            d          }|D ] }|                                }|r|dvr|c S !n# t
          $ r Y nw xY wd
S )u*   获取 tmux 窗口中的活跃进程名。r1   
list-panesr:   -F#{pane_pid}TrR   
r   Npsz--ppidz-ozcomm=z--no-headers)bashzshshfish)r4   r5   rV   stripsplit	Exception)r'   r7   r=   	pane_pidspane_pid	ps_result	processesprocs           r(   get_active_processzTmuxWrapper.get_active_processl   s.   \4t]K
 
 

 M''))//55	 		! 	4Q<	"x4.I#  I
 "(..0066t<<I!    zz||  D(EEEKKK   	 	 	D	 ts   A*C 
C 
CCc                 $   t          j        ddd|ddgdd          }|j                                                            d          }|r|d	         st
          j        S |d	         }	 t          d
| d          }|                                st
          j        S |	                                }|                                }t          |          dk     rt
          j        S |d         }t          d
| d| d          }	|	                                r|		                                                                                                }
|
D ]k}|rgt          d
| d          }|                                r@|	                                                                d         }|dk    rt
          j        c S l|dv rt
          j        S |dk    rt
          j        S t
          j        S # t          t          t           f$ r t
          j        cY S w xY w)u#   检测 PTY 是否在等待输入。r1   rZ   r:   r[   r\   TrR   r]   r   z/proc/z/stat      z/task/z	/childrenR)SDT)r4   r5   rV   rc   rd   r   UNKNOWNr   exists	read_textlenRUNNINGIDLEBLOCKEDFileNotFoundErrorPermissionErrorProcessLookupError)r'   r7   r=   rf   rg   	stat_pathstat_contentpartsstatechildren_pathchildren	child_pid
child_statchild_states                 r(   get_pty_statezTmuxWrapper.get_pty_state   s3   \4t]K
 
 

 M''))//55	 	$	! 	$##Q<	$5h55566I##%% (''$..00L &&((E5zzA~~''!HE !M(!M!M(!M!M!MNNM##%% 8(2244::<<BBDD!) 8 8I  8%)*C9*C*C*C%D%D
%,,.. 8*4*>*>*@*@*F*F*H*H*KK*c11'/'7 7 7 7
""}$#''''!?4FG 	$ 	$ 	$####	$s2   )2G) AG) #CG) :G) G) G) )#HHc                 r    |                      |          }|r|| j        v rt          j        S t          j        S )u   混合模式检测。)rk   r   r   INTERACTIVENATURAL_LANGUAGE)r'   r7   active_procs      r(   detect_modezTmuxWrapper.detect_mode   s<    --l;; 	+;$*DDD**++r*   )r$   )r+   )T)FrN   )__name__
__module____qualname____doc__	frozensetr   r   rT   __annotations__r#   dictr)   intr8   boolr>   rA   rC   rJ   rM   rX   r   rk   r   r   r   r    r*   r(   r	   r	   
   s        ;;3<9 > > > 4 4530   +u+U+$)5+u+U+$)5+ 	u+ U+ %*5+ 	x	+ 	+
 	d+
 F+
 %+F+
 5<W+ 	+ "7+L%S#X'   - -s - - - -
 
c 
 
C 
 
 
 
&3 &4 & & & &
 
 
 
 
 
 S s 3     c  T T    &
S 
 
 
 
 
 
  t QT `c    s x}    <,$# ,$( ,$ ,$ ,$ ,$\, , , , , , , ,r*   r	   )r   r4   pathlibr   typingr   r   butler.session.stater   r   r	   r   r*   r(   <module>r      s                " " " " " " " " 6 6 6 6 6 6 6 6u, u, u, u, u, u, u, u, u, u,r*   