
    `gj9                       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d%dZd&dZd'dZd(d)dZdZ dZ!d(d*dZ"d+d,dZ#edfd-dZ$edfd.dZ%d/dZ&	 	 d0	 	 	 	 	 	 	 	 	 d1dZ'dZ(dZ)e G d d             Z*e G d  d!             Z+d2d"Z,edf	 	 	 	 	 d3d#Z-edfd4d$Z.y)5zHShared helpers for attaching Hermes to a local Chromium-family CDP port.    )annotationsN)	dataclassfield)get_hermes_homei$  z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              #  4   K   | ]  \  }}|D ]  }|   y wN .0names_names       M/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/browser_connect.py	<genexpr>r   '   s!     ZHE1TYZD4Z4Z   c              #  4   K   | ]  \  }}|D ]  }|   y wr   r   )r   r   grouppartss       r   r   r   (   s"     `EZ_`QVu`u`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              #  4   K   | ]  \  }}|D ]  }|   y wr   r   r   s       r   r   r   J   s!     V(%PUVVVr    c              #  4   K   | ]  \  }}|D ]  }|   y wr   r   )r   r   pathspaths       r   r   r   K   s!     ZhaTYZDTZTZr    c           	        g t               d	fd	 	 	 	 	 	 d
fd}| dk(  rt        D ]
  } |        S | dk(  rt        j                  j	                  d      t        j                  j	                  d      t        j                  j	                  d      f}t
        D ]e  \  }}|D ]  } t        j                  |              t        d |      D ]/  }|D ](  } t        j                  j                  |g|        * 1 g S t        D ]6  \  }}	|D ]  } t        j                  |              |	D ]
  }
 |
        8  |dt
               S )Nc                   | sy t         j                  j                  t         j                  j                  |             }|v st         j                  j	                  |       sy j                  |        j                  |       y r   )osr'   normcasenormpathisfileappendadd)r'   
normalized
candidatesseens     r   r/   z(get_chrome_debug_candidates.<locals>.addR   s`    WW%%bgg&6&6t&<=
RWW^^D%9$    c           	         |D ]C  \  }}t        d |       D ]/  }|D ](  } t        j                  j                  |g|        * 1 E y r   )filterr*   r'   join)basesinstall_groupsr   r"   baser#   r/   s         r   add_windows_install_pathsz>get_chrome_debug_candidates.<locals>.add_windows_install_paths[   sW     ' 	4HAutU+ 4" 4ET2E2344	4r3   DarwinWindowsProgramFileszProgramFiles(x86)LOCALAPPDATA)z/mnt/c/Program Filesz/mnt/c/Program Files (x86))r'   
str | NonereturnNone)r7   ztuple[str | None, ...]r8   z?tuple[tuple[tuple[str, ...], tuple[tuple[str, ...], ...]], ...]r@   rA   )set_DARWIN_APPSr*   environget_WINDOWS_BROWSER_GROUPSshutilwhichr5   r'   r6   _LINUX_BROWSER_GROUPS)systemr:   appinstall_basesr   install_partsr   r9   r#   r&   r'   r/   r1   r2   s              @@@r   get_chrome_debug_candidatesrN   N   ss   JUD4%4W4 
4  	CH	JJNN>*JJNN./JJNN>*

 %< 	4 E= (FLL&'(t]3 4* 4ET2E2344	4 - u 	$DT"#	$ 	DI	
 TVmnr3   c                 .    t        t               dz        S )Nzchrome-debug)strr   r   r3   r   chrome_debug_data_dirrQ      s     >122r3   c                *    d|  dt                ddgS )Nz--remote-debugging-port=z--user-data-dir=z--no-first-runz--no-default-browser-check)rQ   )ports    r   _chrome_debug_argsrT      s+    
"4&)
0234$	 r3   c                :   ddl }ddl}ddlm}  |d| v r| nd|        }	 |j                  xs |j
                  dv rdnd}|j
                  d
v rS|j                  j                  d      r8|j                  sy		 |j                  |j                  |f|      5  	 ddd       ydddj                  |j
                  |j
                        }|dvs|j                  sy	| d|j                   j                  d      }| d| dfD ]M  }		 |j                  j!                  |	|      5 }
dt#        |
dd      cxk  rdk  rn n	 ddd        yddd       O y	# t        $ r Y y	w xY w# 1 sw Y   nxY w# t        $ r Y y	w xY w# 1 sw Y   7xY w# t$        $ r Y w xY w)zFReturn True when ``url`` exposes a reachable Chrome DevTools endpoint.r   N)urlparsez://http://>   wsshttpsi  P   F>   wsrX   z/devtools/browser/timeoutThttprY   )r[   rX   >   r^   rY   /z/json/versionz/json   statusi,  )socketurllib.requesturllib.parserV   rS   scheme
ValueErrorr'   
startswithhostnamecreate_connectionOSErrorrE   netlocrstriprequesturlopengetattr	Exception)urlr]   rb   urllibrV   parsedrS   re   rootproberesps              r   is_browser_debug_readyrw      s   %Uc\c?F{{Pfmm7G&GsR }}%&++*@*@AU*V	))6??D*A7)S  
 7+//v}}MF&&fmmXS(//4DF-(TF%.9 	''w'?  4'$#6<<      1     		     		sk    E 8E3 E&E3 
F'FFF	E#"E#&E/+E3 3	E?>E?F	F	FF)	127.0.0.1z[::1])rx   ::1c                L    t         D ]  }d| d|  }t        ||      s|c S  y)ay  Return the first loopback URL (IPv4 first, then IPv6) speaking CDP.

    Dual-stack discovery: when another application squats the IPv4
    loopback on ``port``, a debug browser launched with
    ``--remote-debugging-port`` may bind only ``[::1]``. Probing both
    literals finds it either way. Returns ``None`` when neither
    loopback exposes a CDP discovery endpoint.
    rW   :r\   N)_LOOPBACK_PROBE_HOSTSrw   )rS   r]   hostrq   s       r   discover_local_cdp_urlr~      s9     & vQtf%!#w7J r3   c                    ddl }t        D ]#  }	 |j                  || f|      5  	 ddd        y y# 1 sw Y   nxY w4# t        $ r Y ?w xY w)a  Return True when either loopback accepts TCP on ``port``.

    Callers use this AFTER a failed CDP probe to distinguish "port is
    free, we can launch a browser on it" from "another application
    (IDE debugger, dev server) is squatting the port and a launch
    would fight it".
    r   Nr\   TF)rb   _LOOPBACK_SOCKET_HOSTSri   rj   )rS   r]   rb   r}   s       r   local_port_in_user      sk     & 	))4,)H   	   		s   ?2?;	?	A
A
   c                   ddl }t        | dz   | dz   |z         D ]  }d}|j                  df|j                  dffD ]e  \  }}	 |j                  ||j                        5 }|j                  |j                  |j                  d       |j                  ||f       ddd       g |s|c S  | dz   S # 1 sw Y   xY w# t        $ r d}Y  'w xY w)a|  Return the first port after ``preferred`` bindable on both loopbacks.

    Used when ``preferred`` is occupied by a non-CDP application: rather
    than launching a browser into a bind conflict, pick a nearby free
    port. Falls back to ``preferred + 1`` if nothing binds (the launch
    will then fail with a clear browser-side error instead of silently
    doing nothing).
    r   N   Trx   ry   F)
rb   rangeAF_INETAF_INET6SOCK_STREAM
setsockopt
SOL_SOCKETSO_REUSEADDRbindrj   )	preferredattemptsrb   rS   bindablefamilyr}   socks           r   find_free_debug_portr      s     i!mY]X%=> $nnk:V__e<TU 	LFD]]66+=+=> ,$OOF$5$5v7J7JANIItTl+,	 K q=, ,   s*   B<;B0B<0B95B<<C
Cc                    |xs t        j                         }t        |      }|r@|d   gt        |       }|dk(  rt	        j
                  |      S t        j                  |      S |dk(  rt               }d|  d| dS y )Nr   r<   r;   z7open -a "Google Chrome" --args --remote-debugging-port=z --user-data-dir="z+" --no-first-run --no-default-browser-check)	platformrJ   rN   rT   
subprocesslist2cmdlineshlexr6   rQ   )rS   rJ   r1   argvdata_dirs        r   manual_chrome_debug_commandr      s    (x(F,V4J19 24 8906)0Cz&&t,YTXIYY(*EdV L  (z)TV	

 r3   c                j    | dk7  rddiS t        t        dd      t        t        dd      z  }|rd|iS i S )Nr<   start_new_sessionTDETACHED_PROCESSr   CREATE_NEW_PROCESS_GROUPcreationflags)ro   r   )rJ   flagss     r   _detach_kwargsr     sL    #T**J 2A6.: E (-OU#4"4r3   c                   t        j                         |z   }t        j                         |k  rVt        |t        |d            ry| j	                         yt        j
                  |       t        j                         |k  rVy)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.
    g?r\   readyexitedstarting)time	monotonicr~   minpollsleep)procrS   r]   intervaldeadlines        r   %_wait_for_browser_debug_ready_or_exitr     sk     ~~')H
..
X
% "$Hc0BC99;"

8 ..
X
% r3   zlaunch-stderr.logi  c                  B    e Zd ZU dZded<   ded<   dZded<   dZded	<   y)
LaunchAttemptz/Outcome of one candidate-binary launch attempt.rP   binarystateNz
int | None
returncode stderr_tail)__name__
__module____qualname____doc____annotations__r   r   r   r3   r   r   r   /  s#    9KJ!J
!Kr3   r   c                  N    e Zd ZU dZdZded<    ee      Zded<   e	d
d       Z
y	)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.
    Fboollaunched)default_factoryzlist[LaunchAttempt]r   c                   | j                   D ]T  }|j                  dk(  s|j                  dk(  s#t        j                  j                  |j                        }| d| dc S  | j                   D ]w  }|j                  dk(  s|j                  s t        j                  j                  |j                         d|j                  j                         d   j                          c S  y)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   r*   r'   basenamer   r   
splitlinesstrip)selfattemptr   s      r   hintzChromeDebugLaunch.hintF  s     }} 	G}}(W-?-?1-Dww''7fff 22	 }} 	G}}(W-@-@ww''788^**557;AACDF	 r3   N)r@   r?   )r   r   r   r   r   r   r   listr   propertyr   r   r3   r   r   r   9  s5     Hd$)$$?H!? r3   r   c                    	 t        | d      5 }|j                         }d d d        t         d  j                  dd      j	                         S # 1 sw Y   2xY w# t
        $ r Y yw xY w)Nrbzutf-8replace)errorsr   )openread_STDERR_TAIL_LIMITdecoder   rj   )r'   fhdatas      r   _read_stderr_tailr   [  sq    $ 	779D	''()000KQQSS	 	  s'   A A0A AA 	A('A(c           
     "   |xs t        j                         }t               }t        |      }|st        j                  d|       |S t               }t        j                  |d       t        j                  j                  |t              }|D ]  }	 t        |d      5 }t        j                  |gt        |       ft        j                   |dt#        |      }ddd       t        j                  d
|t-        dd      |        t/        ||       }
t+        ||
      }|j&                  j)                  |       |
dk7  rd|_        |c S t-        |dd      |_        t5        |      |_        t        j9                  d||j2                  | |j6                  rd|j6                   nd        |S # 1 sw Y   xY w# t$        $ rH}	|j&                  j)                  t+        |d             t        j                  d	||	       Y d}	~	zd}	~	ww xY w)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   rJ   r   rN   loggerinforQ   r*   makedirsr'   r6   _LAUNCH_STDERR_LOGr   r   PopenrT   DEVNULLr   rp   r   r.   r   ro   r   r   r   r   r   warning)rS   rJ   resultr1   r   stderr_path	candidatestderr_filer   excr   r   s               r   launch_chrome_debugr   d  s    (x(F F,V4JWY_`$&HKK4('',,x);<K $
		k4( K!'':!3D!9:%--& %V,	 	WD%&		
 6dDAy>w'H"FOM$T<>/<O7>7J7Jog1123PR	
=$
L MI   	OO""=	#XYKKF	SVW	s0   F= =F1F=1F:	6F==	H=H		Hc                .    t        | |      j                  S r   )r   r   )rS   rJ   s     r   try_launch_chrome_debugr     s    tV,555r3   )rJ   rP   r@   	list[str])r@   rP   )rS   intr@   r   )g      ?)rq   rP   r]   floatr@   r   )rS   r   r]   r   r@   r?   )g      ?)rS   r   r]   r   r@   r   )r   r   r   r   r@   r   )rS   r   rJ   r?   r@   r?   )rJ   rP   r@   dict)g       @g?)
r   zsubprocess.PopenrS   r   r]   r   r   r   r@   rP   )r'   rP   r@   rP   )rS   r   rJ   r?   r@   r   )rS   r   rJ   r?   r@   r   )/r   
__future__r   loggingr*   r   r   rG   r   r   dataclassesr   r   hermes_constantsr   	getLoggerr   r   DEFAULT_BROWSER_CDP_PORTDEFAULT_BROWSER_CDP_URLrC   rF   tuple_WINDOWS_BIN_NAMES_WINDOWS_INSTALL_PARTSrI   _LINUX_BIN_NAMES_LINUX_INSTALL_PATHSrN   rQ   rT   rw   r|   r   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r3   r   <module>r      s   N "  	      ( ,			8	$   -.F-GH   Z0GZZ `5L``  @ V.CVV Z2GZZ /d3!P / -  & +CTV 4 -E[_ $5 	

  	
 	4 )        B )t;
;2<;;| )AW[ 6r3   