
    Jj/                       d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZmZ ddlmZ  ej        e          ZdZde ZdZd	Z ed
 eD                       Z ed eD                       ZdZ ed eD                       Z ed eD                       Zd2dZd3dZd4dZd5d6dZedfd7dZ d8d!Z!	 	 d9d:d'Z"d(Z#d)Z$e G d* d+                      Z%e G d, d-                      Z&d;d/Z'edfd<d0Z(edfd=d1Z)dS )>zHShared helpers for attaching Hermes to a local Chromium-family CDP port.    )annotationsN)	dataclassfield)get_hermes_homei$  http://127.0.0.1:)z</Applications/Google Chrome.app/Contents/MacOS/Google Chromez2/Applications/Chromium.app/Contents/MacOS/Chromiumz</Applications/Brave Browser.app/Contents/MacOS/Brave Browserz>/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge)))
chrome.exechrome))GoogleChromeApplicationr   ))chromium.exechromium))Chromiumr   r   )r   r   r   ))	brave.exebrave))BraveSoftwarezBrave-Browserr   r   ))
msedge.exemsedge))	MicrosoftEdger   r   c              #  *   K   | ]\  }}|D ]}|V  d S N .0names_names       @/home/rurouni/.hermes/hermes-agent/hermes_cli/browser_connect.py	<genexpr>r    '   s4      ZZHE1TYZZD4ZZZZZZZ    c              #  *   K   | ]\  }}|D ]}|V  d S r   r   )r   r   grouppartss       r   r    r    (   s5      ``EZ_``QVu```````r!   )))zgoogle-chromezgoogle-chrome-stable)z/opt/google/chrome/chromez/usr/bin/google-chromez/usr/bin/google-chrome-stable))zchromium-browserr   )z/usr/bin/chromium-browserz/usr/bin/chromium))zbrave-browserzbrave-browser-stabler   )z/usr/bin/brave-browserz/usr/bin/brave-browser-stablez/usr/bin/bravez/snap/bin/bravez"/opt/brave.com/brave/brave-browserz/opt/brave.com/brave/bravez/opt/brave-bin/brave))zmicrosoft-edgezmicrosoft-edge-stabler   )z/usr/bin/microsoft-edgez/usr/bin/microsoft-edge-stablez$/opt/microsoft/msedge/microsoft-edgez/opt/microsoft/msedge/msedgec              #  *   K   | ]\  }}|D ]}|V  d S r   r   r   s       r   r    r    J   s4      VV(%PUVVVVVVVVVr!   c              #  *   K   | ]\  }}|D ]}|V  d S r   r   )r   r   pathspaths       r   r    r    K   s4      ZZhaTYZZDTZZZZZZZr!   systemstrreturn	list[str]c           	        g t                      dfddfd
}| dk    rt          D ]} |           S | dk    rt          j                            d          t          j                            d          t          j                            d          f}t
          D ]_\  }}|D ]} t          j        |                      t          d |          D ]'}|D ]"} t          j	        j
        |g|R             #(`S t          D ]7\  }}	|D ]} t          j        |                      |	D ]}
 |
           8 |dt
                     S )Nr(   
str | Noner+   Nonec                &   | sd S t           j                            t           j                            |                     }|v st           j                            |           sd S                     |                                |           d S r   )osr(   normcasenormpathisfileappendadd)r(   
normalized
candidatesseens     r   r6   z(get_chrome_debug_candidates.<locals>.addR   s     	FW%%bg&6&6t&<&<==
RW^^D%9%9F$r!   basestuple[str | None, ...]install_groups?tuple[tuple[tuple[str, ...], tuple[tuple[str, ...], ...]], ...]c           	         |D ]=\  }}t          d |           D ]'}|D ]"} t          j        j        |g|R             #(>d S r   )filterr1   r(   join)r:   r<   r   r#   baser$   r6   s         r   add_windows_install_pathsz>get_chrome_debug_candidates.<locals>.add_windows_install_paths[   s{     ' 	4 	4HAutU++ 4 4" 4 4ECT2E222333344	4 	4r!   DarwinWindowsProgramFileszProgramFiles(x86)LOCALAPPDATA)z/mnt/c/Program Filesz/mnt/c/Program Files (x86))r(   r.   r+   r/   )r:   r;   r<   r=   r+   r/   )set_DARWIN_APPSr1   environget_WINDOWS_BROWSER_GROUPSshutilwhichr?   r(   r@   _LINUX_BROWSER_GROUPS)r)   rB   appinstall_basesr   install_partsr   rA   r$   r'   r(   r6   r8   r9   s              @@@r   get_chrome_debug_candidatesrR   N   s   JUUD      4 4 4 4 4 4  	 	CCHHHHJNN>**JNN.//JNN>**

 %< 	4 	4 E= ( (FL&&''''t]33 4 4* 4 4ECT2E222333344 -  u 	$ 	$DCT""#### 	 	DCIIII	TVmnnnr!   c                 >    t          t                      dz            S )Nzchrome-debug)r*   r   r   r!   r   chrome_debug_data_dirrT      s      >1222r!   portintc                2    d|  dt                       ddgS )Nz--remote-debugging-port=z--user-data-dir=z--no-first-runz--no-default-browser-check)rT   )rU   s    r   _chrome_debug_argsrX      s/    )4))402244$	 r!         ?urltimeoutfloatboolc                $   ddl }ddl}ddlm}  |d| v r| nd|            }	 |j        p|j        dv rdnd}n# t          $ r Y d	S w xY w|j        d
v rn|j                            d          rT|j	        sd	S 	 |
                    |j	        |f|          5  	 ddd           dS # 1 swxY w Y   n# t          $ r Y d	S w xY wddd                    |j        |j                  }|dvs|j        sd	S | d|j                             d          }| d| dfD ]u}		 |j                            |	|          5 }
dt#          |
dd          cxk    rdk     rn n	 ddd            dS ddd           n# 1 swxY w Y   f# t$          $ r Y rw xY wd	S )zFReturn True when ``url`` exposes a reachable Chrome DevTools endpoint.r   N)urlparsez://zhttp://>   wsshttpsi  P   F>   wsr`   z/devtools/browser/r[   Thttpra   )rc   r`   >   re   ra   /z/json/versionz/json   statusi,  )socketurllib.requesturllib.parser_   rU   scheme
ValueErrorr(   
startswithhostnamecreate_connectionOSErrorrJ   netlocrstriprequesturlopengetattr	Exception)rZ   r[   ri   urllibr_   parsedrU   rl   rootproberesps              r   is_browser_debug_readyr}      s   MMM%%%%%%XUc\\cc??F{Pfm7G&G&GssR   uu }%%&+*@*@AU*V*V% 	5	))6?D*A7)SS                   	 	 	55	 7++//v}MMF&&&fm&u((((//44D(((T...9  	''w'??  4'$#66<<<<<<<<<                                                 	 	 	H	5s   9 
AA7B0 B$B0 $B((B0 +B(,B0 0
B>=B>F 9!E4F (F 4E8	8F ;E8	<F  
FFr.   c                   |pt          j                    }t          |          }|rF|d         gt          |           }|dk    rt	          j        |          nt          j        |          S |dk    rt                      }d|  d| dS d S )Nr   rD   rC   z7open -a "Google Chrome" --args --remote-debugging-port=z --user-data-dir="z+" --no-first-run --no-default-browser-check)	platformr)   rR   rX   
subprocesslist2cmdlineshlexr@   rT   )rU   r)   r8   argvdata_dirs        r   manual_chrome_debug_commandr      s    (x((F,V44J Z19 24 8 8906)0C0Cz&t,,,TXIYIYY(**Vd V V (V V V	

 4r!   dictc                    | dk    rddiS t          t          dd          t          t          dd          z  }|rd|ini S )NrD   start_new_sessionTDETACHED_PROCESSr   CREATE_NEW_PROCESS_GROUPcreationflags)rv   r   )r)   flagss     r   _detach_kwargsr      sZ    #T**J 2A66.: : E (-4OU##"4r!          @皙?procsubprocess.Popenintervalc                .   d| }t          j                    |z   }t          j                    |k     rbt          |t          |d                    rdS |                                 dS t          j        |           t          j                    |k     bdS )a+  Classify a launched browser as ready, exited, or still starting.

    We only need to wait long enough to catch the common failure mode where a
    candidate binary exists but exits immediately before exposing the CDP port.
    Slower browsers can still finish starting after this grace window.
    r   g?rd   readyNexitedstarting)time	monotonicr}   minpollsleep)r   rU   r[   r   cdp_urldeadlines         r   %_wait_for_browser_debug_ready_or_exitr      s     )$((G~')H
.

X
%
%!'3x3E3EFFF 	799;;"8
8 .

X
%
% :r!   zlaunch-stderr.logi  c                  D    e Zd ZU dZded<   ded<   dZded<   dZded	<   dS )
LaunchAttemptz/Outcome of one candidate-binary launch attempt.r*   binarystateNz
int | None
returncode stderr_tail)__name__
__module____qualname____doc____annotations__r   r   r   r!   r   r   r      sL         99KKKJJJ!J!!!!Kr!   r   c                  \    e Zd ZU dZdZded<    ee          Zded<   e	dd
            Z
dS )ChromeDebugLaunchaL  Structured result of ``launch_chrome_debug``.

    ``launched`` mirrors the legacy boolean contract: a launch command was
    executed and the browser is ready or still starting (it does NOT
    guarantee the CDP port ever opens). ``attempts`` carries per-candidate
    diagnostics so callers can explain *why* nothing came up.
    Fr]   launched)default_factoryzlist[LaunchAttempt]attemptsr+   r.   c                   | j         D ]F}|j        dk    r9|j        dk    r.t          j                            |j                  }| d| dc S G| j         D ]n}|j        dk    ra|j        rZt          j                            |j                   d|j                                        d         	                                 c S odS )z>Best user-facing explanation for a failed/soft launch, if any.r   r   uJ    exited immediately without opening the debug port — an already-running z instance likely absorbed the launch (Chromium's single-instance behavior). Close ALL of its processes (including background/tray instances) and retry /browser connect.z& exited before the debug port opened: N)
r   r   r   r1   r(   basenamer   r   
splitlinesstrip)selfattemptr   s      r   hintzChromeDebugLaunch.hint   s    } 	 	G}((W-?1-D-Dw''77 2 22 2 2   } 	 	G}((W-@(w''77 F F*5577;AACCF F   tr!   N)r+   r.   )r   r   r   r   r   r   r   listr   propertyr   r   r!   r   r   r      so           H$)E$$?$?$?H????   X  r!   r   r(   c                   	 t          | d          5 }|                                }d d d            n# 1 swxY w Y   |t           d                              dd                                          S # t
          $ r Y dS w xY w)Nrbzutf-8replace)errorsr   )openread_STDERR_TAIL_LIMITdecoder   rq   )r(   fhdatas      r   _read_stderr_tailr     s    $ 	7799D	 	 	 	 	 	 	 	 	 	 	 	 	 	 	''(()000KKQQSSS   rrs,   A5 3A5 7A5 79A5 5
BBc           
     x   |pt          j                    }t                      }t          |          }|st                              d|           |S t                      }t          j        |d           t          j	        
                    |t                    }|D ]}	 t          |d          5 }t          j        |gt          |           ft          j        |dt#          |          }ddd           n# 1 swxY w Y   n\# t$          $ rO}	|j                            t+          |d                     t                              d	||	           Y d}	~	d}	~	ww xY wt                              d
|t-          |dd          |            t/          ||           }
t+          ||
          }|j                            |           |
dk    rd|_        |c S t-          |dd          |_        t5          |          |_        t                              d||j        | |j        r
d|j         nd           |S )uV  Launch a Chromium-family browser with remote debugging, with diagnostics.

    Tries each detected candidate binary in turn. A candidate that exits
    before the CDP port opens (crash, singleton forward to an existing
    instance, bad profile dir) is logged — with exit code and a stderr tail —
    and the next candidate is tried.
    zAbrowser debug launch: no Chromium-family binary found (system=%s)T)exist_okwb)stdoutstderrNzspawn-failed)r   r   z,browser debug launch: failed to spawn %s: %szIbrowser debug launch: spawned %s (pid=%s) with --remote-debugging-port=%dpidr   r   zAbrowser debug launch: %s exited (code=%s) before port %d opened%sz; stderr tail: r   )r   r)   r   rR   loggerinforT   r1   makedirsr(   r@   _LAUNCH_STDERR_LOGr   r   PopenrX   DEVNULLr   rw   r   r5   r   rv   r   r   r   r   r   warning)rU   r)   resultr8   r   stderr_path	candidatestderr_filer   excr   r   s               r   launch_chrome_debugr     s    (x((F  F,V44J WY_```$&&HK4((((',,x);<<K $
 $
		k4(( K!':!3D!9!9:%-&  %V,,	                 	 	 	O""=	#X#X#XYYYKKF	SVWWWHHHH	
 	WD%&&		
 	
 	
 6dDAAy>>>w'''H"FOMMM$T<>>/<<O7>7JR3g1333PR	
 	
 	
 	
 Ms=   !D1=C:.D:C>	>DC>	D
EAEEc                ,    t          | |          j        S r   )r   r   )rU   r)   s     r   try_launch_chrome_debugr   \  s    tV,,55r!   )r)   r*   r+   r,   )r+   r*   )rU   rV   r+   r,   )rY   )rZ   r*   r[   r\   r+   r]   )rU   rV   r)   r.   r+   r.   )r)   r*   r+   r   )r   r   )
r   r   rU   rV   r[   r\   r   r\   r+   r*   )r(   r*   r+   r*   )rU   rV   r)   r.   r+   r   )rU   rV   r)   r.   r+   r]   )*r   
__future__r   loggingr1   r   r   rL   r   r   dataclassesr   r   hermes_constantsr   	getLoggerr   r   DEFAULT_BROWSER_CDP_PORTDEFAULT_BROWSER_CDP_URLrH   rK   tuple_WINDOWS_BIN_NAMES_WINDOWS_INSTALL_PARTSrN   _LINUX_BIN_NAMES_LINUX_INSTALL_PATHSrR   rT   rX   r}   r   r   r   r   r   r   r   r   r   r   r   r!   r   <module>r      s   N N " " " " " "  				         ( ( ( ( ( ( ( ( , , , , , ,		8	$	$   H.FHH   UZZ0GZZZZZ ``5L`````  @ 5VV.CVVVVV uZZ2GZZZZZ / / / /d3 3 3 3   ! ! ! ! !H -E[_     $5 5 5 5 	    2 )                  B    )t; ; ; ; ;| )AW[ 6 6 6 6 6 6 6r!   