§
    ‰eîi  ã                   ó  — U d 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 ddl	m
Z
  e
e¦  «        j        j                             ¦   «         ZddlmZ ddlmZmZmZ ddlmZmZmZmZmZmZ ddlmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ dd	l%m&Z&m'Z'  ed
¬¦  «         G d„ d¦  «        ¦   «         Z(de)fd„Z*de+de+dz  fd„Z,de+de-fd„Z.de+de-fd„Z/de+de0de-fd„Z1de2e+         de+dz  de)e+         ddfd„Z3�dŽde)e+         de-de2e+         fd„Z4�d�de)dz  de-de2fd„Z5�dŽde-de6e-e-f         fd„Z7	 	 �d�de-d!e6e8d"f         de9e8e8f         fd#„Z:ddd$d%œde-d&e+dz  d'e0de-fd(„Z;�d‘de-d&e+dz  de-fd)„Z<de-fd*„Z=�dŽde-de(fd+„Z>d,d-œde6e+d"f         e2e+         z  d.e+dz  de8fd/„Z?d0e(ddfd1„Z@	 	 �d’d2e-de)dz  de-de+fd3„ZAde-fd4„ZBde-fd5„ZCdd6lDmEZEmFZFmGZG de-fd7„ZH�dŽde-de-fd8„ZIde-fd9„ZJde-fd:„ZKde-fd;„ZLde-fd<„ZMd=ZNd>ZOde8fd?„ZP�d“d@e8dz  de8fdA„ZQde8fdB„ZR�dŽde-de
fdC„ZS G dD„ dEeT¦  «        ZUde
fdF„ZV�d”dG„ZW�d•d'e0de-fdI„ZXd
dJœdKe-ddfdL„ZYdMe8dNe8dOe8ddfdP„ZZ�dŽde-de2e8         fdQ„Z[�dŽde-de2e8         fdR„Z\ddSœdTe2e8         de-dej]        fdU„Z^�dŽde-de8fdV„Z_de2e8         fdW„Z`de-fdX„ZadYZbe6e8d"f         ecdZ<   d[Zde6e8d"f         ecd\<   de2e6e-e
f                  fd]„Zede2e6e8e
e-f                  fd^„Zfde-fd_„Zg�d”d`„Zh	 	 �d–dae-dbe-de6e+e2e
         f         fdc„Zi�d”dd„Zjdee8ddfdf„Zk�d“dge8dz  de6e8e8e8f         fdh„Zldie
de8dz  fdj„Zmde8dz  fdk„Znde8dz  fdl„Zo�dŽd2e-de6e8dz  e-f         fdm„Zpde6e-dz  e8f         fdn„Zq�d”do„Zrde
fdp„Zsde
fdq„Ztde
dz  fdr„Zude8fds„Zvdte
due2e8         de2e8         fdv„Zwdwe8dxe8de8fdy„Zxdxe8de8fdz„Zy�d‘de-dge8dz  de8fd{„Zzd|e8de8fd}„Z{d|e8de8fd~„Z|�dŽde-de-fd„Z}�dŽde-de-fd€„Z~�d“dMe8d�e8dz  ddfd‚„Z�d”dƒ„Z€�dŽde-de-fd„„Z�de0fd…„Z‚�d—d2e-de-dge8dz  fd†„Zƒ�dŽde-fd‡„Z„�dŽde-fdˆ„Z…�dŽde-fd‰„Z†�dŽde-fdŠ„Z‡�d˜d‹e-de-dŒe-fd�„Zˆde8fdŽ„Z‰de8fd�„ZŠde8fd�„Z‹de-fd‘„ZŒde-fd’„Z��dŽd2e-fd“„ZŽd”„ Z�d•„ Z�d–„ Z‘�d™d'e0d™e0dz  de-fdš„Z’d›„ Z“�dŽd‹e-fdœ„Z”�dšd�e+dže-dŸe-fd „Z•d¡d¢d£d¤g d¥¢d¤d¦d
d§d¨œd©dªdd
d«d¬œd­d®dd¯d¨œgd°œd±d²d³d´g dµ¢d´d¦d
d¶d¨œd·d¸dd
d¹d¬œdºd®dd»d¨œgd°œd¼d½d¾d¿g dÀ¢d¿dÁd
dÂd¨œdÃdÄd
dÅd¨œdÆdªdd
dÇd¬œgd°œdÈdÉdÊdËg 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¨œgd°œdÛdÜd³dÝg 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¨œgd°œdêdëdìdídîœdïdðdñdòdîœdódôdõdög 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¬œgd°œ�d�dd£�dg �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¨œgd°œ�d�dd³�dg �d¢�d�dd�dd¨œ�d�dd
�d d¨œgd°œ�d!�d"�d#�d$g �d%¢�d$�d&d�d'd¨œ�d(�d)d
�d*d¨œ�d+�d,d�d-d¨œ�d.�d/d�d0d¨œ�d1�d2dd
�d3d¬œ�d4�d5d�d6d¨œgd°œ�d7�d8d³�d9g �d:¢�d9�d;d�d<d¨œ�d=�d>d
�d?d¨œ�d@�d2dd
�dAd¬œ�dB�d5d�d6d¨œgd°œ�dC�dDd³�dEg �dF¢�dE�dGd�dHd¨œ�dI�dJd
�dKd¨œ�dL�dMd�dNd¨œ�dO�dPd
�dQd¨œ�dR�dSd
�dTd¨œ�dU�dVd�dWd¨œ�dX�d2dd
�dYd¬œgd°œ�dZ�d[d³�d\dîœ�d]�d^d³�d_g �d`¢�d_�dad�dbd¨œ�dc�ddd
�ded¨œ�df�dgdd
�dhd¬œ�di�djd�dkd¨œgd°œ�dl�dm�dn�dog �dp¢�do�dqd�drd¨œ�ds�dtd
�dud¨œ�dv�dwdd
�dxd¬œ�dy�dzd�d{d¨œgd°œgZ–�d|e9de8f�d}„Z—de2e8         f�d~„Z˜�d|e9f�d„Z™�d€„ Zš�d�„ Z›�d‚„ Zœ�dƒ„ Z��d„„ Zžde-f�d…„ZŸde-f�d†„Z �d‡„ Z¡�dˆ„ Z¢�d‰„ Z£�dŠ„ Z¤�d‹„ Z¥�dŒ„ Z¦�d�„ Z§dS (›  zu
Gateway subcommand for hermes CLI.

Handles: hermes gateway [run|start|stop|restart|status|install|uninstall|setup]
é    N)Ú	dataclass)ÚPath)Úterminate_pid)Ú%DEFAULT_GATEWAY_RESTART_DRAIN_TIMEOUTÚ!GATEWAY_SERVICE_RESTART_EXIT_CODEÚparse_restart_drain_timeout)Úget_env_valueÚget_hermes_homeÚ
is_managedÚmanaged_errorÚread_raw_configÚsave_env_value)Úprint_headerÚ
print_infoÚprint_successÚprint_warningÚprint_errorÚpromptÚprompt_choiceÚprompt_yes_no)ÚColorsÚcolorT)Úfrozenc                   ó    — e Zd ZU eed<   dZeed<   dZeed<   dZe	e
df         ed<   dZedz  ed	<   ed
efd„¦   «         Zed
efd„¦   «         ZdS )ÚGatewayRuntimeSnapshotÚmanagerFÚservice_installedÚservice_running© .Úgateway_pidsNÚservice_scopeÚreturnc                 ó8   — | j         pt          | j        ¦  «        S ©N)r   Úboolr    ©Úselfs    ú4/home/div/.hermes/hermes-agent/hermes_cli/gateway.pyÚrunningzGatewayRuntimeSnapshot.running6   s   € àÔ#Ð>¥t¨DÔ,=Ñ'>Ô'>Ð>ó    c                 ó.   — | j         o| j        o| j         S r$   )r   r)   r   r&   s    r(   Úhas_process_service_mismatchz3GatewayRuntimeSnapshot.has_process_service_mismatch:   s   € àÔ%ÐS¨$¬,ÐS¸tÔ?SÐ;SÐSr*   )Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__r   r%   r   r    ÚtupleÚintr!   Úpropertyr)   r,   r   r*   r(   r   r   .   s¿   € € € € € € à€L€L�LØ#Ð�tÐ#Ð#Ñ#Ø!€O�TÐ!Ð!Ñ!Ø$&€L�%˜˜S˜”/Ð&Ð&Ñ&Ø $€M�3˜‘:Ð$Ð$Ñ$àð?˜ð ?ð ?ð ?ñ „Xð?ð ðT¨dð Tð Tð Tñ „XðTð Tð Tr*   r   r"   c            	      óž  — t          ¦   «         } t          ¦   «         �r,ddgdgfD �]#}	 t          j        |g d¢z   ddd¬¦  «        }|j                             ¦   «                              ¦   «         D ]¹}|                     ¦   «         }|r|d                              d¦  «        sŒ4|d         }	 t          j        |d	|d
dgz   ddd¬¦  «        }t          |j                             ¦   «         ¦  «        }|dk    r|  
                    |¦  «         Œž# t          t          j        f$ r Y Œ¶w xY w�Œ# t          t          j        f$ r Y �Œ!w xY wt          ¦   «         rõ	 t          ¦   «         }t          j        dd|gddd¬¦  «        }|j        dk    r£|j                             ¦   «                              ¦   «         D ]w}|                     ¦   «         }t#          |¦  «        dk    rN|d         |k    rB	 t          |d         ¦  «        }|dk    r|  
                    |¦  «         Œg# t          $ r Y Œsw xY wŒxn# t          t          j        f$ r Y nw xY w| S )ao  Return PIDs currently managed by systemd or launchd gateway services.

    Used to avoid killing freshly-restarted service processes when sweeping
    for stale manual gateway processes after a service restart.  Relies on the
    service manager having committed the new PID before the restart command
    returns (true for both systemd and launchd in practice).
    Ú	systemctlú--user)z
list-unitszhermes-gateway*z--plainz--no-legendú
--no-pagerTé   ©Úcapture_outputÚtextÚtimeoutr   ú.serviceÚshowz--property=MainPIDú--valueÚ	launchctlÚlisté   é   )ÚsetÚsupports_systemd_servicesÚ
subprocessÚrunÚstdoutÚstripÚ
splitlinesÚsplitÚendswithr3   ÚaddÚ
ValueErrorÚTimeoutExpiredÚFileNotFoundErrorÚis_macosÚget_launchd_labelÚ
returncodeÚlen)	ÚpidsÚ
scope_argsÚresultÚlineÚpartsÚsvcr?   ÚpidÚlabels	            r(   Ú_get_service_pidsr^   >   sÇ  € õ ‘”€Dõ !Ñ"Ô"ñ Ø'¨Ð2°[°MÐBð 	ñ 	ˆJðÝ#œØð "Jð "Jð "Jñ Jà#'¨d¸Aðñ ô �ð
 #œM×/Ò/Ñ1Ô1×<Ò<Ñ>Ô>ð ð �DØ ŸJšJ™LœL�EØ ð !¨¨a¬×(9Ò(9¸*Ñ(EÔ(Eð !Ø Ø œ(�Cð
Ý)œ~Ø&¨&°#Ø*>À	ð*Kñ Kà+/°dÀAð ñ  ô  ˜õ
 " $¤+×"3Ò"3Ñ"5Ô"5Ñ6Ô6˜Ø š7˜7Ø ŸHšH S™MœM˜MøøÝ&­
Ô(AÐBð ð ð Ø˜ðøøøñøõ  &¥zÔ'@ÐAð ð ð Ø‘ðøøøõ �z„zð ð	Ý%Ñ'Ô'ˆEÝ”^Ø˜f eÐ,Ø#¨$¸ðñ ô ˆFð Ô  AÒ%Ð%à"œM×/Ò/Ñ1Ô1×<Ò<Ñ>Ô>ð !ð !�DØ ŸJšJ™LœL�EÝ˜5‘z”z Q’�¨5°¬8°uÒ+<Ð+<ð!Ý"% e¨A¤h¡-¤-˜CØ" Qšw˜wØ $§¢¨¡¤ øøÝ)ð !ð !ð !Ø ˜Dð!øøøøøøå!¥:Ô#<Ð=ð 	ð 	ð 	ØˆDð	øøøð €Ksn   ©BD-Â.A DÄD-ÄD(Ä%D-Ä'D(Ä(D-Ä-EÅEÅBH1 Ç.0HÈH1 È
H,È)H1 È+H,È,H1 È1I
É	I
r\   c           	      ó¤  — | dk    rdS 	 t          j        ddddt          | ¦  «        gddd¬	¦  «        }n# t          t           j        f$ r Y dS w xY w|j        d
k    rdS |j                             ¦   «         }|sdS 	 t          | 	                    ¦   «         d                              ¦   «         ¦  «        }n# t          $ r Y dS w xY w|d
k    r|ndS )z@Return the parent PID for ``pid``, or ``None`` when unavailable.é   NÚpsú-ozppid=z-pTr9   r:   r   éÿÿÿÿ)rG   rH   r0   rQ   rP   rT   rI   rJ   r3   rK   rO   )r\   rX   ÚrawÚ
parent_pids       r(   Ú_get_parent_pidrf   }   s  € à
ˆa‚x€xØˆtðÝ”Ø�4˜ $­¨C©¬Ð1ØØØð	
ñ 
ô 
ˆˆøõ �zÔ8Ð9ð ð ð ØˆtˆtðøøøàÔ˜AÒÐØˆtØ
Œ-×
Ò
Ñ
Ô
€CØð ØˆtðÝ˜ŸšÑ)Ô)¨"Ô-×3Ò3Ñ5Ô5Ñ6Ô6ˆ
ˆ
øÝð ð ð Øˆtˆtðøøøà# aš˜ˆ:ˆ:¨TÐ1s!   Š*5 µAÁAÁ=9B7 Â7
CÃCÚ
target_pidc                 óÌ   — | dk    rdS t          j        ¦   «         }t          ¦   «         }|r8||vr4|| k    rdS |                     |¦  «         t	          |¦  «        pd}|r||v°4dS )zHReturn True when ``target_pid`` is this process or one of its ancestors.r   FT)ÚosÚgetpidrE   rN   rf   )rg   r\   Úseens      r(   Ú#_is_pid_ancestor_of_current_processrl   –   s~   € à�Q‚€Øˆuå
Œ)‰+Œ+€CÝ‘U”U€DØ
ð (�#˜T�/�/Ø�*ÒÐØ�4Ø�Š�‰ŒˆÝ˜cÑ"Ô"Ð' aˆð	 ð (�#˜T�/�/ð
 ˆ5r*   c                 óÔ   — t          t          d¦  «        sdS t          | ¦  «        sdS 	 t          j        | t          j        ¦  «         n# t          t          t          f$ r Y dS w xY wdS )z@Ask a running gateway ancestor to restart itself asynchronously.ÚSIGUSR1FT)	ÚhasattrÚsignalrl   ri   Úkillrn   ÚProcessLookupErrorÚPermissionErrorÚOSError)r\   s    r(   Ú_request_gateway_self_restartru   ¥   sx   € å•6˜9Ñ%Ô%ð ØˆuÝ.¨sÑ3Ô3ð ØˆuðÝ
Œ�•V”^Ñ$Ô$Ð$Ð$øÝ¥µÐ9ð ð ð Øˆuˆuðøøøàˆ4s   ªA
 Á
A%Á$A%Údrain_timeoutc                 ó  — t          t          d¦  «        sdS | dk    rdS 	 t          j        | t          j        ¦  «         n$# t
          $ r Y dS t          t          f$ r Y dS w xY wddl}| 	                    ¦   «         t          |d¦  «        z   }| 	                    ¦   «         |k     r`	 t          j        | d¦  «         n# t
          $ r Y dS t          $ r Y nw xY w|                     d¦  «         | 	                    ¦   «         |k     °`dS )a‚  Send SIGUSR1 to a gateway PID and wait for it to exit gracefully.

    SIGUSR1 is wired in gateway/run.py to ``request_restart(via_service=True)``
    which drains in-flight agent runs (up to ``agent.restart_drain_timeout``
    seconds), then exits with code 75.  Both systemd (``Restart=on-failure``
    + ``RestartForceExitStatus=75``) and launchd (``KeepAlive.SuccessfulExit
    = false``) relaunch the process after the graceful exit.

    This is the drain-aware alternative to ``systemctl restart`` / ``SIGTERM``,
    which SIGKILL in-flight agents after a short timeout.

    Args:
        pid: Gateway process PID (systemd MainPID, launchd PID, or bare
            process PID).
        drain_timeout: Seconds to wait for the process to exit after sending
            SIGUSR1.  Should be slightly larger than the gateway's
            ``agent.restart_drain_timeout`` to allow the drain loop to
            finish cleanly.

    Returns:
        True if the PID was signalled and exited within the timeout.
        False if SIGUSR1 couldn't be sent or the process didn't exit in
        time (caller should fall back to a harder restart path).
    rn   Fr   TNg      ð?ç      à?)ro   rp   ri   rq   rn   rr   rs   rt   ÚtimeÚ	monotonicÚmaxÚsleep)r\   rv   Ú_timeÚdeadlines       r(   Ú_graceful_restart_via_sigusr1r   ²   sI  € õ2 •6˜9Ñ%Ô%ð ØˆuØ
ˆa‚x€xØˆuðÝ
Œ�•V”^Ñ$Ô$Ð$Ð$øÝð ð ð àˆtˆtÝ�WÐ%ð ð ð Øˆuˆuðøøøð ÐÐÐà�ŠÑ Ô ¥3 }°cÑ#:Ô#:Ñ:€HØ
�/Š/Ñ
Ô
˜hÒ
&Ð
&ð	ÝŒG�C˜‰OŒOˆOˆOøÝ!ð 	ð 	ð 	Ø�4�4Ýð 	ð 	ð 	ð ˆDð	øøøð 	�Š�CÑÔÐð �/Š/Ñ
Ô
˜hÒ
&Ð
&ð ˆ5s/   ¡A Á
A"ÁA"Á!A"Â'B= Â=
CÃ
	CÃCrV   Úexclude_pidsc                 ó†   — |�|dk    rd S |t          j        ¦   «         k    s||v s|| v rd S |                      |¦  «         d S )Nr   )ri   rj   Úappend)rV   r\   r€   s      r(   Ú_append_unique_pidrƒ   è   sT   € Ø
€{�c˜Q’h�hØˆØ
�bŒi‰kŒkÒÐ˜S LÐ0Ð0°C¸4°K°KØˆØ‡K‚K�ÑÔÐÐÐr*   FÚall_profilesc                 óT  ‡‡‡‡— g }g d¢}t          t          ¦   «                              ¦   «         ¦  «        Št          ‰¦  «        }|r|                     ¦   «         d         ndŠdt           dt
          fˆˆfd„}	 t          ¦   «         �rt          j        g d¢ddd	¬
¦  «        }|j	        dk    rg S dŠ|j
                             d¦  «        D ]É}|                     ¦   «         }|                     d¦  «        r|t          d¦  «        d…         ŠŒC|                     d¦  «        rq|t          d¦  «        d…         }t          ˆfd„|D ¦   «         ¦  «        r=|s |‰¦  «        r0	 t          |t!          |¦  «        | ¦  «         n# t"          $ r Y nw xY wdŠŒÊ�npt          j        g d¢ddd	¬
¦  «        }|j	        dk    rg S |j
                             d¦  «        D �]-}|                     ¦   «         }	|	rd|	v rŒd}
dŠ|	                     dd¦  «        }t          |¦  «        dk    r1	 t!          |d         ¦  «        }
|d         Šn# t"          $ r d}
Y nw xY w|
€s|	                     ¦   «         }t          |¦  «        d	k    rL|d                              ¦   «         r2t!          |d         ¦  «        }
d                     |d	d…         ¦  «        Š|
€Œôt          ˆfd„|D ¦   «         ¦  «        r|s |‰¦  «        rt          ||
| ¦  «         �Œ/n# t(          t          j        f$ r g cY S w xY w|S )a	  Best-effort process-table scan for gateway PIDs.

    This supplements the profile-scoped PID file so status views can still spot
    a live gateway when the PID file is stale/missing, and ``--all`` sweeps can
    discover gateways outside the current profile.
    )úhermes_cli.main gatewayzhermes_cli.main --profilezhermes_cli.main -púhermes_cli/main.py gatewayzhermes_cli/main.py --profilezhermes_cli/main.py -pzhermes gatewayúgateway/run.pyrc   Ú Úcommandr"   c                 ód   •— ‰rd‰› �| v pd‰› �| v pd‰› �| v S d| v sd| v rdS d| v r	d‰› �| vrdS dS )Nú
--profile z-p zHERMES_HOME=z -p FTr   )rŠ   Úcurrent_homeÚcurrent_profile_names    €€r(   Ú_matches_current_profilez4_scan_gateway_pids.<locals>._matches_current_profile  s�   ø€ Øð 	à3Ð1Ð3Ð3°wÐ>ð <Ø/Ð-Ð/Ð/°7Ð:ð<à0 ,Ð0Ð0°GÐ;ðð ˜7Ð"Ð" f°Ð&7Ð&7Ø�5Ø˜WÐ$Ð$Ð)F¸Ð)FÐ)FÈgÐ)UÐ)UØ�5Øˆtr*   )ÚwmicÚprocessÚgetzProcessId,CommandLinez/FORMAT:LISTTé
   r:   r   ú
zCommandLine=Nz
ProcessId=c              3   ó    •K  — | ]}|‰v V — Œ	d S r$   r   )Ú.0ÚpÚcurrent_cmds     €r(   ú	<genexpr>z%_scan_gateway_pids.<locals>.<genexpr>%  s(   øè è € Ð>Ð>°˜1 Ð+Ð>Ð>Ð>Ð>Ð>Ð>r*   )ra   z-AÚewwrb   zpid=,command=Úgrepr`   rD   ú c              3   ó    •K  — | ]}|‰v V — Œ	d S r$   r   )r–   ÚpatternrŠ   s     €r(   r™   z%_scan_gateway_pids.<locals>.<genexpr>N  s(   øè è € ÐBÐB¨g�w 'Ð)ÐBÐBÐBÐBÐBÐBr*   )r0   r
   ÚresolveÚ_profile_argrL   r%   Ú
is_windowsrG   rH   rT   rI   rJ   Ú
startswithrU   Úanyrƒ   r3   rO   ÚisdigitÚjoinrt   rP   )r€   r„   rV   ÚpatternsÚcurrent_profile_argr�   rX   rY   Úpid_strÚstrippedr\   rZ   Ú	aux_partsrŠ   r˜   r�   rŽ   s                @@@@r(   Ú_scan_gateway_pidsr«   ð   sñ  øøøø€ ð €Dð	ð 	ð 	€Hõ •Ñ(Ô(×0Ò0Ñ2Ô2Ñ3Ô3€LÝ& |Ñ4Ô4ÐØ>QÐYÐ.×4Ò4Ñ6Ô6°rÔ:Ð:ÐWYÐð­#ð µ$ð ð ð ð ð ð ð ð?Ý‰<Œ<ñ <	@Ý”^ØSÐSÐSØ#ØØð	ñ ô ˆFð Ô  AÒ%Ð%Ø�	ØˆKØœ×+Ò+¨DÑ1Ô1ð %ð %�Ø—z’z‘|”|�Ø—?’? >Ñ2Ô2ð %Ø"&¥s¨>Ñ':Ô':Ð';Ð';Ô"<�K�KØ—_’_ \Ñ2Ô2ð 	%Ø"¥3 |Ñ#4Ô#4Ð#5Ð#5Ô6�GÝÐ>Ð>Ð>Ð>°XÐ>Ñ>Ô>Ñ>Ô>ð !Ø$ð!Ø(@Ð(@ÀÑ(MÔ(Mð!ð!Ý.¨tµS¸±\´\À<ÑPÔPÐPÐPøÝ)ð !ð !ð !Ø ˜Dð!øøøà"$�Køñ%õ  ”^Ø:Ð:Ð:Ø#ØØð	ñ ô ˆFð Ô  AÒ%Ð%Ø�	Øœ×+Ò+¨DÑ1Ô1ð @ñ @�ØŸ:š:™<œ<�Øð  6¨XÐ#5Ð#5Øà�Ø�à Ÿš t¨QÑ/Ô/�Ý�u‘:”: ’?�?ð#Ý! %¨¤(™mœm˜Ø"'¨¤(˜˜øÝ%ð #ð #ð #Ø"˜˜˜ð#øøøð �;Ø (§¢Ñ 0Ô 0�IÝ˜9‘~”~¨Ò*Ð*¨y¸¬|×/CÒ/CÑ/EÔ/EÐ*Ý! )¨A¤,Ñ/Ô/˜Ø"%§(¢(¨9°R°S°S¬>Ñ":Ô":˜à�;ØÝÐBÐBÐBÐB¸ÐBÑBÔBÑBÔBð @Ø ð@Ø$<Ð$<¸WÑ$EÔ$Eð@õ ' t¨S°,Ñ?Ô?Ð?ùøøÝ•ZÔ.Ð/ð ð ð Øˆ	ˆ	ˆ	ðøøøð €Ksi   Á;5L
 Â1B3L
 Å%FÆL
 Æ
FÆL
 ÆFÆ.L
 Ç A%L
 È&IÉL
 ÉIÉL
 ÉIÉB6L
 Ì
L%Ì$L%c                 ó8  — t          | pt          ¦   «         ¦  «        }g }|s1	 ddlm} t          | |¦   «         |¦  «         n# t          $ r Y nw xY wt          ¦   «         D ]}t          |||¦  «         Œt          ||¬¦  «        D ]}t          |||¦  «         Œ|S )a  Find PIDs of running gateway processes.

    Args:
        exclude_pids: PIDs to exclude from the result (e.g. service-managed
            PIDs that should not be killed during a stale-process sweep).
        all_profiles: When ``True``, return gateway PIDs across **all**
            profiles (the pre-7923 global behaviour).  ``hermes update``
            needs this because a code update affects every profile.
            When ``False`` (default), only PIDs belonging to the current
            Hermes profile are returned.
    r   ©Úget_running_pid©r„   )rE   Úgateway.statusr®   rƒ   Ú	Exceptionr^   r«   )r€   r„   Ú_excluderV   r®   r\   s         r(   Úfind_gateway_pidsr³   X  sÛ   € õ �<Ð(¥3¡5¤5Ñ)Ô)€HØ€DØð ð	Ø6Ð6Ð6Ð6Ð6Ð6å˜t _ _Ñ%6Ô%6¸ÑAÔAÐAÐAøÝð 	ð 	ð 	ØˆDð	øøøå Ñ"Ô"ð 0ð 0ˆÝ˜4  hÑ/Ô/Ð/Ð/Ý! (¸ÐFÑFÔFð 0ð 0ˆÝ˜4  hÑ/Ô/Ð/Ð/Ø€Ks   £A Á
AÁAÚsystemc                 ó6  — t          | ¦  «        }t          |¬¦  «                             ¦   «         }|s|dfS 	 t          dt	          ¦   «         g|ddd¬¦  «        }n # t
          t          j        f$ r |dfcY S w xY w||j         	                    ¦   «         dk    fS )N©r´   Fú	is-activeTr“   ©r´   r;   r<   r=   Úactive)
Ú_select_systemd_scopeÚget_systemd_unit_pathÚexistsÚ_run_systemctlÚget_service_nameÚRuntimeErrorrG   rP   rI   rJ   )r´   Úselected_systemÚunit_existsrX   s       r(   Ú_probe_systemd_service_runningrÂ   t  sÈ   € Ý+¨FÑ3Ô3€OÝ'¨Ð?Ñ?Ô?×FÒFÑHÔH€KØð &Ø Ð%Ð%ð	&ÝØÕ*Ñ,Ô,Ð-Ø"ØØØð
ñ 
ô 
ˆˆøõ �*Ô3Ð4ð &ð &ð &Ø Ð%Ð%Ð%Ð%ð&øøøà˜FœM×/Ò/Ñ1Ô1°XÒ=Ð=Ð=s   ¹"A ÁA9Á8A9©ÚActiveStateÚSubStateÚResultÚExecMainStatusÚ
properties.c           	      ó   — t          | ¦  «        }	 t          dt          ¦   «         ddd                     |¦  «        g|ddd¬¦  «        }n$# t          t
          j        t          f$ r i cY S w xY w|j        dk    ri S i }|j	         
                    ¦   «         D ]7}d	|vrŒ|                     d	d
¦  «        \  }}|                     ¦   «         ||<   Œ8|S )zCReturn selected ``systemctl show`` properties for the gateway unit.r?   r8   z
--propertyú,Tr“   r¸   r   ú=r`   )rº   r½   r¾   r¥   r¿   rG   rP   rt   rT   rI   rK   rL   rJ   )r´   rÈ   rÀ   rX   ÚparsedrY   ÚkeyÚvalues           r(   Ú_read_systemd_unit_propertiesrÏ   †  s  € õ ,¨FÑ3Ô3€OðÝàÝ Ñ"Ô"ØØØ—’˜Ñ$Ô$ðð #ØØØð
ñ 
ô 
ˆˆøõ �*Ô3µWÐ=ð ð ð Øˆ	ˆ	ˆ	ðøøøð Ô˜AÒÐØˆ	à€FØ”×(Ò(Ñ*Ô*ð $ð $ˆØ�dˆ?ˆ?ØØ—Z’Z  QÑ'Ô'‰
ˆˆUØ—k’k‘m”mˆˆs‰ˆØ€Ms   ‘8A
 Á
A+Á*A+g      N@)r´   Úprevious_pidr=   rÐ   r=   c                 ó  — ddl }t          ¦   «         }t          | ¦  «                             ¦   «         }|                      ¦   «         |z   }|                      ¦   «         |k     rðt	          | ¬¦  «        }|                     dd¦  «        }|                     dd¦  «        }	d}
	 ddlm}  |¦   «         }
n# t          $ r d}
Y nw xY w|dk    r9|
r |�|
|k    rt          d	|› d
|
› d�¦  «         dS |€t          d	|› d�¦  «         dS |dk    r|	dk    r| 
                    d¦  «         ŒÛ| 
                    d¦  «         |                      ¦   «         |k     °ðt          d|› dt          |¦  «        › d| rdnd› d| sdnd› d|› d�¦  «         dS )zFWait for the gateway service to become active after a restart handoff.r   Nr¶   rÄ   r‰   rÅ   r­   r¹   õ   âœ“ z service restarted (PID ú)Tú service restartedÚ
activatingúauto-restartr`   rD   õ   âš  z& service did not become active within zs.
  Check status: úsudo z1hermes gateway status
  Check logs:   journalctl ú--user z-u z -l --since '2 min ago'F)ry   r¾   Ú_service_scope_labelÚ
capitalizerÏ   r’   r°   r®   r±   Úprintr|   r3   )r´   rÐ   r=   ry   r[   Úscope_labelr~   ÚpropsÚactive_stateÚ	sub_stateÚnew_pidr®   s               r(   Ú!_wait_for_systemd_service_restartrâ   ®  s  € ð €K€K€Kå
Ñ
Ô
€CÝ& vÑ.Ô.×9Ò9Ñ;Ô;€KØ�yŠy‰{Œ{˜WÑ$€Hà
�)Š)‰+Œ+˜Ò
 Ð
 Ý-°VÐ<Ñ<Ô<ˆØ—y’y °Ñ3Ô3ˆØ—I’I˜j¨"Ñ-Ô-ˆ	Øˆð	Ø6Ð6Ð6Ð6Ð6Ð6à%�oÑ'Ô'ˆGˆGøÝð 	ð 	ð 	ØˆGˆGˆGð	øøøð ˜8Ò#Ð#Øð ˜LÐ0°G¸|Ò4KÐ4KÝÐL˜[ÐLÐLÀ'ÐLÐLÐLÑMÔMÐMØ�tØÐ#ÝÐ<˜[Ð<Ð<Ð<Ñ=Ô=Ð=Ø�tà˜<Ò'Ð'¨I¸Ò,GÐ,GØ�JŠJ�q‰MŒMˆMØà�
Š
�1‰Œˆð1 �)Š)‰+Œ+˜Ò
 Ð
 õ4 
ð	gˆ{ð 	gð 	gÅ#ÀgÁ,Ä,ð 	gð 	gØ&,Ð4˜7˜7°"ð	gð 	gà7=Ð&E i iÀ2ð	gð 	gàJMð	gð 	gð 	gñô ð ð
 ˆ5s   Â"B3 Â3CÃCc                 ó  — t          | ¬¦  «        }|sdS 	 ddlm} n# t          $ r Y dS w xY w |¦   «         pi }|                     d¦  «        sdS |                     dd¦  «        }|                     dd¦  «        }|                     d	d¦  «        }|                     d
d¦  «        }|dk    r&|dk    r t          d¦  «         t          | |¬¦  «        S |dk    r­|t          t          ¦  «        k    s|dk    r�t          ¦   «         }	t          | ¦  «                             ¦   «         }
t          d|
                     ¦   «         › d�¦  «         t          d|	g| dd¬¦  «         t          d|	g| dd¬¦  «         t          | |¬¦  «        S dS )zARecover a planned service restart that is stuck in systemd state.r¶   Fr   ©Úread_runtime_statusÚrestart_requestedrÄ   r‰   rÅ   rÇ   rÆ   rÕ   rÖ   uG   â�³ Service restart already pending â€” waiting for systemd relaunch...©r´   rÐ   Úfailedz	exit-codeu&   â†» Clearing failed state for pending z service restart...úreset-failedé   ©r´   Úcheckr=   ÚstartéZ   )rÏ   r°   rå   r±   r’   rÜ   râ   r0   r   r¾   rÚ   rÛ   Úlowerr½   )r´   rÐ   rÞ   rå   Úruntime_staterß   rà   Úexec_main_statusrX   r[   rÝ   s              r(   Ú _recover_pending_systemd_restartrò   Ý  s  € å)°Ð8Ñ8Ô8€EØð ØˆuðØ6Ð6Ð6Ð6Ð6Ð6Ð6øÝð ð ð Øˆuˆuðøøøð (Ð'Ñ)Ô)Ð/¨R€MØ×ÒÐ0Ñ1Ô1ð Øˆuà—9’9˜]¨BÑ/Ô/€LØ—	’	˜* bÑ)Ô)€IØ—y’yÐ!1°2Ñ6Ô6ÐØ�YŠY�x Ñ$Ô$€Fà�|Ò#Ð#¨	°^Ò(CÐ(CÝÐWÑXÔXÐXÝ0ØØ%ð
ñ 
ô 
ð 	
ð
 �xÒÐØ�CÕ AÑBÔBÒBÐBØ�[Ò Ð åÑ Ô ˆÝ*¨6Ñ2Ô2×=Ò=Ñ?Ô?ˆÝÐ_°{×7HÒ7HÑ7JÔ7JÐ_Ð_Ð_Ñ`Ô`Ð`ÝØ˜SÐ!ØØØð		
ñ 	
ô 	
ð 	
õ 	Ø�cˆNØØØð		
ñ 	
ô 	
ð 	
õ 1ØØ%ð
ñ 
ô 
ð 	
ð
 ˆ5s   – �
+ª+c                  óÚ   — t          ¦   «                              ¦   «         sdS 	 t          j        ddt	          ¦   «         gddd¬¦  «        } n# t          j        $ r Y dS w xY w| j        dk    S )NFrA   rB   Tr“   r:   r   )Úget_launchd_plist_pathr¼   rG   rH   rS   rP   rT   )rX   s    r(   Ú_probe_launchd_service_runningrõ     s�   € Ý!Ñ#Ô#×*Ò*Ñ,Ô,ð ØˆuðÝ”Ø˜&Õ"3Ñ"5Ô"5Ð6ØØØð	
ñ 
ô 
ˆˆøõ Ô$ð ð ð ØˆuˆuðøøøàÔ Ò!Ð!s   ¤'A ÁAÁAc                 ó^  — t          t          ¦   «         ¦  «        }t          ¦   «         rt          d|¬¦  «        S ddlm} t          ¦   «         r |¦   «         rt          d|¬¦  «        S t          ¦   «         rZt          | ¬¦  «        \  }}t          |¦  «        }t          d|› d�t          |¬¦  «                             ¦   «         |||¬	¦  «        S t          ¦   «         r>t          d
t          ¦   «                              ¦   «         t          ¦   «         |d
¬	¦  «        S t          d|¬¦  «        S )zBReturn a unified view of gateway liveness for the current profile.zTermux / manual process)r   r    r   )Úis_containerzdocker (foreground)r¶   z	systemd (rÓ   )r   r   r   r    r!   Úlaunchdzmanual process)r2   r³   Ú	is_termuxr   Úhermes_constantsr÷   Úis_linuxrF   rÂ   rÚ   r»   r¼   rR   rô   rõ   )r´   r    r÷   rÀ   r   rÝ   s         r(   Úget_gateway_runtime_snapshotrü   "  so  € åÕ*Ñ,Ô,Ñ-Ô-€LÝ�{„{ð 
Ý%Ø-Ø%ð
ñ 
ô 
ð 	
ð
 .Ð-Ð-Ð-Ð-Ð-å�z„zð 
�l�l‘n”nð 
Ý%Ø)Ø%ð
ñ 
ô 
ð 	
õ
 !Ñ"Ô"ð 	
Ý+IÐQWÐ+XÑ+XÔ+XÑ(ˆ˜Ý*¨?Ñ;Ô;ˆÝ%Ø. Ð.Ð.Ð.Ý3¸?ÐKÑKÔK×RÒRÑTÔTØ+Ø%Ø%ð
ñ 
ô 
ð 	
õ �z„zð 
Ý%ØÝ4Ñ6Ô6×=Ò=Ñ?Ô?Ý:Ñ<Ô<Ø%Ø#ð
ñ 
ô 
ð 	
õ "Ø Ø!ðñ ô ð r*   rC   ©Úlimitrþ   c                óÄ   — |�d„ | d |…         D ¦   «         nd„ | D ¦   «         }|�(t          | ¦  «        |k    r|                     d¦  «         d                     |¦  «        S )Nc                 ó8   — g | ]}|d k    ¯t          |¦  «        ‘ŒS ©r   ©r0   ©r–   r\   s     r(   ú
<listcomp>z(_format_gateway_pids.<locals>.<listcomp>N  s#   € Ð<Ð<Ð<˜S°C¸!²G°G•�C‘”°G°G°Gr*   c                 ó8   — g | ]}|d k    ¯t          |¦  «        ‘ŒS r  r  r  s     r(   r  z(_format_gateway_pids.<locals>.<listcomp>N  s/   € ÐW|ÐW|ÐW|ÐehÐtwÐz{Òt{Ðt{ÕX[Ð\_ÑX`ÔX`Ðt{Ðt{Ðt{r*   z...ú, )rU   r‚   r¥   )rV   rþ   Úrendereds      r(   Ú_format_gateway_pidsr  M  sr   € Ø@EÐ@QÐ<Ð< D¨¨%¨¤LÐ<Ñ<Ô<Ð<ÐW|ÐW|ÐlpÐW|ÑW|ÔW|€HØÐ�S ™YœY¨Ò.Ð.Ø�Š˜ÑÔÐØ�9Š9�XÑÔÐr*   Úsnapshotc                 óÚ   — | j         sd S t          ¦   «          t          d¦  «         t          dt          | j        d ¬¦  «        › �¦  «         t          d¦  «         t          d¦  «         d S )NuN   âš  Gateway process is running for this profile, but the service is not activez
  PID(s): rý   zI  This is usually a manual foreground/tmux/nohup run, so `hermes gateway`z<  can refuse to start another copy until this process stops.)r,   rÜ   r  r    )r	  s    r(   Ú_print_gateway_process_mismatchr  T  sv   € ØÔ0ð ØˆÝ	�G„G€GÝ	Ð
ZÑ[Ô[Ð[Ý	Ð
PÕ+¨HÔ,AÈÐNÑNÔNÐ
PÐ
PÑQÔQÐQÝ	Ð
UÑVÔVÐVÝ	Ð
HÑIÔIÐIÐIÐIr*   Úforcec                 ó  — t          ||¬¦  «        }d}|D ]m}	 t          || ¬¦  «         |dz  }Œ# t          $ r Y Œ&t          $ r t	          d|› �¦  «         Y ŒCt
          $ r}t	          d|› d|› �¦  «         Y d}~Œfd}~ww xY w|S )	a–  Kill any running gateway processes. Returns count killed.

    Args:
        force: Use the platform's force-kill mechanism instead of graceful terminate.
        exclude_pids: PIDs to skip (e.g. service-managed PIDs that were just
            restarted and should not be killed).
        all_profiles: When ``True``, kill across all profiles.  Passed
            through to :func:`find_gateway_pids`.
    )r€   r„   r   ©r  r`   õ"   âš  Permission denied to kill PID zFailed to kill PID ú: N)r³   r   rr   rs   rÜ   rt   )r  r€   r„   rV   Úkilledr\   Úexcs          r(   Úkill_gateway_processesr  ^  så   € õ ¨,À\ÐRÑRÔR€DØ€Fàð 6ð 6ˆð
	6Ý˜# UÐ+Ñ+Ô+Ð+Ø�a‰KˆFˆFøÝ!ð 	ð 	ð 	àˆDÝð 	>ð 	>ð 	>ÝÐ<°sÐ<Ð<Ñ=Ô=Ð=Ð=Ð=åð 	6ð 	6ð 	6ÝÐ4¨Ð4Ð4¨sÐ4Ð4Ñ5Ô5Ð5Ð5Ð5Ð5Ð5Ð5øøøøð	6øøøà€Ms    ™0°
B¼BÁ	BÁ"A<Á<Bc                  óÐ  — 	 ddl m} m} n# t          $ r Y dS w xY w | ¦   «         }|€dS 	 t	          j        |t          j        ¦  «         n.# t          $ r Y n"t          $ r t          d|› �¦  «         Y dS w xY wddl}t          d¦  «        D ]E}	 t	          j        |d¦  «         |                     d¦  «         Œ.# t          t          f$ r Y  nw xY w | ¦   «         €
 |¦   «          dS )	u   Stop only the gateway for the current profile (HERMES_HOME-scoped).

    Uses the PID file written by start_gateway(), so it only kills the
    gateway belonging to this profile â€” not gateways from other profiles.
    Returns True if a process was stopped, False if none was found.
    r   )r®   Úremove_pid_fileFNr  é   rx   T)r°   r®   r  ÚImportErrorri   rq   rp   ÚSIGTERMrr   rs   rÜ   ry   Úranger|   )r®   r  r\   r}   Ú_s        r(   Ústop_profile_gatewayr  {  s_  € ðØCÐCÐCÐCÐCÐCÐCÐCÐCøÝð ð ð Øˆuˆuðøøøð ˆ/Ñ
Ô
€CØ
€{ØˆuðÝ
Œ�•V”^Ñ$Ô$Ð$Ð$øÝð ð ð ØˆÝð ð ð ÝÐ8°3Ð8Ð8Ñ9Ô9Ð9Øˆuˆuðøøøð
 ÐÐÐÝ�2‰YŒYð ð ˆð	ÝŒG�C˜‰OŒOˆOØ�KŠK˜ÑÔÐÐøÝ"¥OÐ4ð 	ð 	ð 	ØˆEˆEð	øøøð €ÑÔÐ ØˆÑÔÐØˆ4s5   ‚ ‹
˜«A Á
A6ÁA6Á5A6Â*B:Â:CÃCc                  ó@   — t           j                             d¦  «        S )NÚlinux)ÚsysÚplatformr¢   r   r*   r(   rû   rû   ¡  s   € ÝŒ<×"Ò" 7Ñ+Ô+Ð+r*   )r÷   rù   Úis_wslc                  ó"   — t          d¬¦  «        S )u¿   Check if systemd is actually running as PID 1 on WSL.

    WSL2 with ``systemd=true`` in wsl.conf has working systemd.
    WSL2 without it (or WSL1) does not â€” systemctl commands fail.
    Tr¶   ©Ú_systemd_operationalr   r*   r(   Ú_wsl_systemd_operationalr$  ¨  s   € õ   tÐ,Ñ,Ô,Ð,r*   c                 óÒ   — 	 t          dg| ddd¬¦  «        }|j                             ¦   «                              ¦   «         }|dv S # t          t
          j        t          f$ r Y dS w xY w)z7Return True when the requested systemd scope is usable.zis-system-runningTr9   r¸   )r)   ÚdegradedÚstartingÚinitializingF)r½   rI   rJ   rï   r¿   rG   rP   rt   )r´   rX   Ústatuss      r(   r#  r#  ±  s†   € ðÝØ Ð!ØØØØð
ñ 
ô 
ˆð ”×$Ò$Ñ&Ô&×,Ò,Ñ.Ô.ˆØÐLÐLÐLøÝ�*Ô3µWÐ=ð ð ð Øˆuˆuðøøøs   ‚AA ÁA&Á%A&c                  óN   — t          d¬¦  «        rdS t          d¬¦  «        rdS dS )zDReturn True when a container exposes working user or system systemd.Fr¶   Tr"  r   r*   r(   Ú_container_systemd_operationalr+  Â  s7   € å 5Ð)Ñ)Ô)ð ØˆtÝ 4Ð(Ñ(Ô(ð ØˆtØˆ5r*   c                  óÞ   — t          ¦   «         rt          ¦   «         rdS t          j        d¦  «        €dS t	          ¦   «         rt          ¦   «         S t          ¦   «         rt          ¦   «         S dS )NFr6   T)rû   rù   ÚshutilÚwhichr   r$  r÷   r+  r   r*   r(   rF   rF   Ë  sh   € Ý‰:Œ:ð �™œð ØˆuÝ„|�KÑ Ô Ð(ØˆuÝ�x„xð *Ý'Ñ)Ô)Ð)Ý�~„~ð 0Ý-Ñ/Ô/Ð/Øˆ4r*   c                  ó"   — t           j        dk    S )NÚdarwin©r  r  r   r*   r(   rR   rR   ×  s   € ÝŒ<˜8Ò#Ð#r*   c                  ó"   — t           j        dk    S )NÚwin32r1  r   r*   r(   r¡   r¡   Ú  s   € ÝŒ<˜7Ò"Ð"r*   zhermes-gatewayz5Hermes Agent Gateway - Messaging Platform Integrationc                  ó:  — ddl } ddl}ddlm} t	          ¦   «                              ¦   «         } |¦   «                              ¦   «         }||k    rdS |dz                       ¦   «         }	 |                     |¦  «        }|j        }t          |¦  «        dk    r$| 	                    d|d         ¦  «        r|d         S n# t          $ r Y nw xY w|                      t          |¦  «                             ¦   «         ¦  «                             ¦   «         dd…         S )	a  Derive a service-name suffix from the current HERMES_HOME.

    Returns ``""`` for the default root, the profile name for
    ``<root>/profiles/<name>``, or a short hash for any other path.
    Works correctly in Docker (HERMES_HOME=/opt/data) and standard deployments.
    r   N©Úget_default_hermes_rootr‰   Úprofilesr`   ú^[a-z0-9][a-z0-9_-]{0,63}$é   )ÚhashlibÚrerú   r6  r
   rŸ   Úrelative_torZ   rU   ÚmatchrO   Úsha256r0   ÚencodeÚ	hexdigest)r:  r;  r6  ÚhomeÚdefaultÚprofiles_rootÚrelrZ   s           r(   Ú_profile_suffixrE  æ  s'  € ð €N€N€NØ€I€I€IØ8Ð8Ð8Ð8Ð8Ð8ÝÑÔ×$Ò$Ñ&Ô&€DØ%Ð%Ñ'Ô'×/Ò/Ñ1Ô1€GØˆw‚€Øˆrà˜zÑ)×2Ò2Ñ4Ô4€MðØ×Ò˜}Ñ-Ô-ˆØ”	ˆÝˆu‰:Œ:˜Š?ˆ?˜rŸxšxÐ(EÀuÈQÄxÑPÔPˆ?Ø˜”8ˆOøøÝð ð ð Øˆðøøøð �>Š>�#˜d™)œ)×*Ò*Ñ,Ô,Ñ-Ô-×7Ò7Ñ9Ô9¸"¸1¸"Ô=Ð=s   Á+AB? Â?
CÃCÚhermes_homec                 óØ  — ddl }ddlm} t          | pt	          t          ¦   «         ¦  «        ¦  «                             ¦   «         } |¦   «                              ¦   «         }||k    rdS |dz                       ¦   «         }	 |                     |¦  «        }|j        }t          |¦  «        dk    r'| 
                    d|d         ¦  «        rd|d         › �S n# t          $ r Y nw xY wdS )	a×  Return ``--profile <name>`` only when HERMES_HOME is a named profile.

    For ``~/.hermes/profiles/<name>``, returns ``"--profile <name>"``.
    For the default profile or hash-based custom paths, returns the empty string.

    Args:
        hermes_home: Optional explicit HERMES_HOME path. Defaults to the current
            ``get_hermes_home()`` value. Should be passed when generating a
            service definition for a different user (e.g. system service).
    r   Nr5  r‰   r7  r`   r8  rŒ   )r;  rú   r6  r   r0   r
   rŸ   r<  rZ   rU   r=  rO   )rF  r;  r6  rA  rB  rC  rD  rZ   s           r(   r    r      s  € ð €I€I€IØ8Ð8Ð8Ð8Ð8Ð8Ý�Ð5�s¥?Ñ#4Ô#4Ñ5Ô5Ñ6Ô6×>Ò>Ñ@Ô@€DØ%Ð%Ñ'Ô'×/Ò/Ñ1Ô1€GØˆw‚€ØˆrØ˜zÑ)×2Ò2Ñ4Ô4€MðØ×Ò˜}Ñ-Ô-ˆØ”	ˆÝˆu‰:Œ:˜Š?ˆ?˜rŸxšxÐ(EÀuÈQÄxÑPÔPˆ?Ø*  a¤Ð*Ð*Ð*øøÝð ð ð Øˆðøøøàˆ2s   ÂAC Ã
C'Ã&C'c                  óH   — t          ¦   «         } | st          S t          › d| › �S )a  Derive a systemd service name scoped to this HERMES_HOME.

    Default ``~/.hermes`` returns ``hermes-gateway`` (backward compatible).
    Profile ``~/.hermes/profiles/coder`` returns ``hermes-gateway-coder``.
    Any other HERMES_HOME appends a short hash for uniqueness.
    ú-)rE  Ú_SERVICE_BASE©Úsuffixs    r(   r¾   r¾     s1   € õ ÑÔ€FØð ÝÐÝÐ&Ð&˜fÐ&Ð&Ð&r*   c                 ó�   — t          ¦   «         }| rt          d¦  «        |› d�z  S t          j        ¦   «         dz  dz  dz  |› d�z  S )Nú/etc/systemd/systemr>   ú.configÚsystemdÚuser)r¾   r   rA  )r´   Únames     r(   r»   r»   +  s[   € ÝÑÔ€DØð ?ÝÐ)Ñ*Ô*°Ð->Ð->Ð->Ñ>Ð>ÝŒ9‰;Œ;˜Ñ" YÑ.°Ñ7¸TÐ:KÐ:KÐ:KÑKÐKr*   c                   ó   — e Zd ZdZdS )ÚUserSystemdUnavailableErrora#  Raised when ``systemctl --user`` cannot reach the user D-Bus session.

    Typically hit on fresh RHEL/Debian SSH sessions where linger is disabled
    and no user@.service is running, so ``/run/user/$UID/bus`` never exists.
    Carries a user-facing remediation message in ``args[0]``.
    N)r-   r.   r/   Ú__doc__r   r*   r(   rT  rT  2  s   € € € € € ðð ð ð r*   rT  c                  ó�   — t           j                             d¦  «        pdt          j        ¦   «         › �} t	          | ¦  «        dz  S )zIReturn the expected per-user D-Bus socket path (regardless of existence).ÚXDG_RUNTIME_DIRú
/run/user/Úbus)ri   Úenvironr’   Úgetuidr   )Úxdgs    r(   Ú_user_dbus_socket_pathr]  ;  s;   € å
Œ*�.Š.Ð*Ñ
+Ô
+Ð
IÐ/I½B¼I¹K¼KÐ/IÐ/I€CÝ�‰9Œ9�uÑÐr*   c                  óŒ  — t          j        ¦   «         } dt           j        vr5d| › �}t          |¦  «                             ¦   «         r|t           j        d<   dt           j        vr]t           j                             dd| › �¦  «        }t          |¦  «        dz  }|                     ¦   «         rd|› �t           j        d<   dS dS dS )a­  Ensure DBUS_SESSION_BUS_ADDRESS and XDG_RUNTIME_DIR are set for systemctl --user.

    On headless servers (SSH sessions), these env vars may be missing even when
    the user's systemd instance is running (via linger).  Without them,
    ``systemctl --user`` fails with "Failed to connect to bus: No medium found".
    We detect the standard socket path and set the vars so all subsequent
    subprocess calls inherit them.
    rW  rX  ÚDBUS_SESSION_BUS_ADDRESSrY  z
unix:path=N)ri   r[  rZ  r   r¼   r’   )ÚuidÚruntime_dirÚxdg_runtimeÚbus_paths       r(   Ú_ensure_user_systemd_envrd  A  sÒ   € õ Œ)‰+Œ+€CØ¥¤
Ð*Ð*Ø( 3Ð(Ð(ˆÝ�ÑÔ×#Ò#Ñ%Ô%ð 	8Ø,7�BŒJÐ(Ñ)à!­¬Ð3Ð3Ý”j—n’nÐ%6Ð8JÀSÐ8JÐ8JÑKÔKˆÝ˜Ñ$Ô$ uÑ,ˆØ�?Š?ÑÔð 	MØ5LÀ(Ð5LÐ5L�BŒJÐ1Ñ2Ð2Ð2ð	 4Ð3ð	Mð 	Mr*   ç      @c                 ób  — ddl }|                     ¦   «         | z   }|                     ¦   «         |k     r]t          ¦   «                              ¦   «         rt	          ¦   «          dS |                     d¦  «         |                     ¦   «         |k     °]t          ¦   «                              ¦   «         S )zéPoll for the user D-Bus socket to appear, up to ``timeout`` seconds.

    Linger-enabled user@.service can take a second or two to spawn the socket
    after ``loginctl enable-linger`` runs.  Returns True once the socket exists.
    r   NTgš™™™™™É?)ry   rz   r]  r¼   rd  r|   )r=   ry   r~   s      r(   Ú_wait_for_user_dbus_socketrg  W  s¡   € ð €K€K€Kà�~Š~ÑÔ 'Ñ)€HØ
�.Š.Ñ
Ô
˜XÒ
%Ð
%Ý!Ñ#Ô#×*Ò*Ñ,Ô,ð 	Ý$Ñ&Ô&Ð&Ø�4Ø�
Š
�3‰Œˆð	 �.Š.Ñ
Ô
˜XÒ
%Ð
%õ
 "Ñ#Ô#×*Ò*Ñ,Ô,Ð,r*   )Úauto_enable_lingerrh  c                 óZ  — t          ¦   «          t          ¦   «         }|                     ¦   «         rdS ddl}|                     ¦   «         }t          ¦   «         \  }}|du r9t          d¬¦  «        rdS t          |ddt          j	        ¦   «         › d�¬	¦  «         | rõt          j        d
¦  «        rá	 t          j        d
d|gdddd¬¦  «        }|j        dk    rFt          d¬¦  «        rt          d|› d�¦  «         dS t          |ddt!          ¦   «         › �¬	¦  «         |j        p|j        p	d|j        › �                     ¦   «         }t          |d|› �d|› �¬	¦  «         n0# t(          $ r#}t          |d|› d�d|› �¬	¦  «         Y d}~nd}~ww xY wt          |d|pd› d�d|› �¬	¦  «         dS )a  Ensure ``systemctl --user`` will reach the user D-Bus session bus.

    No-op when the bus socket is already there (the common case on desktops
    and linger-enabled servers).  On fresh SSH sessions where the socket is
    missing:

    * If linger is already enabled, wait briefly for user@.service to spawn
      the socket.
    * If linger is disabled and ``auto_enable_linger`` is True, try
      ``loginctl enable-linger $USER`` (works as non-root when polkit permits
      it, otherwise needs sudo).
    * If the socket is still missing afterwards, raise
      :class:`UserSystemdUnavailableError` with a precise remediation message.

    Callers should treat the exception as a terminal condition for user-scope
    systemd operations and surface the message to the user.
    Nr   Tre  ©r=   z;User D-Bus socket is missing even though linger is enabled.z  systemctl start user@zC.service
  (may require sudo; try again after the command succeeds))ÚreasonÚfix_hintÚloginctlúenable-lingerFrê   ©r;   r<   rì   r=   ç      @u   âœ“ Enabled linger for u    â€” user D-Bus now availablez=Linger was enabled, but the user D-Bus socket did not appear.z`  Log out and log back in, then re-run the command.
  Or reboot and run: systemctl --user start úexit z#loginctl enable-linger was denied: z  sudo loginctl enable-linger zloginctl enable-linger failed (ú).z%User D-Bus session is not available (zlinger disabled)rd  r]  r¼   ÚgetpassÚgetuserÚget_systemd_linger_statusrg  Ú_raise_user_systemd_unavailableri   r[  r-  r.  rG   rH   rT   rÜ   r¾   ÚstderrrI   rJ   r±   )	rh  rc  rs  ÚusernameÚlinger_enabledÚlinger_detailrX   Údetailr  s	            r(   Ú_preflight_user_systemdr|  h  sŸ  € õ$ ÑÔÐÝ%Ñ'Ô'€HØ‡‚ÑÔð Øˆà€N€N€Nà�ŠÑ Ô €HÝ$=Ñ$?Ô$?Ñ!€N�Mà˜ÐÐÝ%¨cÐ2Ñ2Ô2ð 	ØˆFå'ØØPðM­"¬)©+¬+ð Mð Mð Mð		
ñ 	
ô 	
ð 	
ð ð "�fœl¨:Ñ6Ô6ð "ð!	Ý”^Ø˜_¨hÐ7Ø#ØØØðñ ô ˆFð Ô  AÒ%Ð%Ý-°cÐ:Ñ:Ô:ð ÝÐ[°HÐ[Ð[Ð[Ñ\Ô\Ð\Ø�Få/ØØZð\ÝGWÑGYÔGYð\ð \ð	ñ ô ð ð ”mÐS v¤}ÐSÐ8SÀÔ@QÐ8SÐ8S×ZÒZÑ\Ô\ˆFÝ+ØØE¸VÐEÐEØD¸(ÐDÐDðñ ô ð ð øõ+ ð 	ð 	ð 	Ý+ØØ@¸Ð@Ð@Ð@ØD¸(ÐDÐDðñ ô ð ð ð ð ð ð øøøøð	øøøõ6 $Øð7ØÐ2Ð!2ð7ð 7ð 7ð =°(Ð<Ð<ðñ ô ð ð ð s   Â0E  Å 
FÅ*FÆFrx  rk  rl  c                ó0   — |› d|› d�}t          |¦  «        ‚)zHBuild a user-facing error message and raise UserSystemdUnavailableError.zR
  systemctl --user cannot reach the user D-Bus session in this shell.

  To fix:
z{

  Alternative: run the gateway in the foreground (stays up until
  you exit / close the terminal):
    hermes gateway run)rT  )rx  rk  rl  Úmsgs       r(   rv  rv  ¿  s:   € ð ð 	!ð 	!ð ð		!ð 	!ð 	!ð õ & cÑ
*Ô
*Ð*r*   c                 ó4   — | st          ¦   «          | rdgnddgS )Nr6   r7   )rd  r¶   s    r(   Ú_systemctl_cmdr€  Ï  s,   € Øð #Ý Ñ"Ô"Ð"Ø"Ð?ˆKˆ=ˆ=¨°hÐ(?Ð?r*   c                 ó   — | rdgnddgS )NÚ
journalctlr7   r   r¶   s    r(   Ú_journalctl_cmdrƒ  Õ  s   € Ø#ÐAˆLˆ>ˆ>¨,¸Ð)AÐAr*   r¶   Úargsc                ó„   — 	 t          j        t          |¦  «        | z   fi |¤ŽS # t          $ r t	          d¦  «        d‚w xY w)a%  Run a systemctl command, raising RuntimeError if systemctl is missing.

    Defense-in-depth: callers are gated by ``supports_systemd_services()``,
    but this ensures any future caller that bypasses the gate still gets a
    clear error instead of a raw ``FileNotFoundError`` traceback.
    z)systemctl is not available on this systemN)rG   rH   r€  rQ   r¿   )r„  r´   Úkwargss      r(   r½   r½   Ù  s_   € ðÝŒ~�n¨VÑ4Ô4°tÑ;ÐFÐF¸vÐFÐFÐFøÝð ð ð ÝØ7ñ
ô 
àð	ðøøøs   ‚!$ ¤?c                 ó   — | rdndS )Nr´   rQ  r   r¶   s    r(   rÚ   rÚ   è  s   € ØÐ)ˆ8ˆ8 6Ð)r*   c                  óÜ   — g } t          ¦   «         }dD ]X\  }}t          |¬¦  «        }||v rŒ|                     ¦   «         r*|                      |¦  «         |                     |¦  «         ŒY| S )N))FrQ  )Tr´   r¶   )rE   r»   r¼   r‚   rN   )ÚscopesÚ
seen_pathsr´   r]   Ú	unit_paths        r(   Úget_installed_systemd_scopesrŒ  ì  s   € Ø€FÝ™EœE€JØ<ð &ð &‰ˆ�Ý)°Ð8Ñ8Ô8ˆ	Ø˜
Ð"Ð"ØØ×ÒÑÔð 	&Ø�MŠM˜%Ñ Ô Ð Ø�NŠN˜9Ñ%Ô%Ð%øØ€Mr*   c                  ó@   — t          t          ¦   «         ¦  «        dk    S )Nr`   )rU   rŒ  r   r*   r(   Úhas_conflicting_systemd_unitsrŽ  ù  s   € ÝÕ+Ñ-Ô-Ñ.Ô.°Ò2Ð2r*   )zhermes.serviceÚ_LEGACY_SERVICE_NAMES)r†   r‡   rˆ   z hermes gateway z/hermes gateway Ú_LEGACY_UNIT_EXECSTART_MARKERSc                  ó`   — dt          j        ¦   «         dz  dz  dz  fdt          d¦  «        fgS )u¾   Return ``[(is_system, base_dir), ...]`` â€” directories to scan for legacy units.

    Factored out so tests can monkeypatch the search roots without touching
    real filesystem paths.
    FrO  rP  rQ  TrN  )r   rA  r   r*   r(   Ú_legacy_unit_search_pathsr’    s<   € ð 
•”	‘”˜iÑ'¨)Ñ3°fÑ<Ð=Ø	�tÐ)Ñ*Ô*Ð+ðð r*   c                  óN  ‡— g } t          ¦   «         D ]’\  }}t          D ]…}||z  }	 |                     ¦   «         sŒ|                     dd¬¦  «        Šn# t          t
          f$ r Y ŒHw xY wt          ˆfd„t          D ¦   «         ¦  «        sŒm|                      |||f¦  «         Œ†Œ“| S )uÐ  Return ``[(unit_name, unit_path, is_system)]`` for legacy Hermes gateway units.

    Detects unit files installed by older Hermes versions that used a
    different service name (e.g. ``hermes.service`` before the rename to
    ``hermes-gateway.service``). When both a legacy unit and the current
    ``hermes-gateway.service`` are active, they fight over the same bot
    token â€” the PR #5646 signal-recovery change turns this into a 30-second
    SIGTERM flap loop.

    Safety guards:

    * Explicit allowlist of legacy names (no globbing). Profile units such
      as ``hermes-gateway-coder.service`` and unrelated third-party
      ``hermes-*`` services are never matched.
    * ExecStart content check â€” only flag units that invoke our gateway
      entrypoint. A user-created ``hermes.service`` running an unrelated
      binary is left untouched.
    * Results are returned purely for caller inspection; this function
      never mutates or removes anything.
    úutf-8Úignore)ÚencodingÚerrorsc              3   ó    •K  — | ]}|‰v V — Œ	d S r$   r   )r–   Úmarkerr<   s     €r(   r™   z,_find_legacy_hermes_units.<locals>.<genexpr>9  s'   øè è € ÐSÐS¨&�v �~ÐSÐSÐSÐSÐSÐSr*   )	r’  r�  r¼   Ú	read_textrt   rs   r£   r�  r‚   )ÚresultsÚ	is_systemÚbaserR  r‹  r<   s        @r(   Ú_find_legacy_hermes_unitsrž    sç   ø€ ð* -/€GÝ4Ñ6Ô6ð 9ð 9‰ˆ	�4Ý)ð 	9ð 	9ˆDØ˜t™ˆIðØ ×'Ò'Ñ)Ô)ð ØØ ×*Ò*°GÀHÐ*ÑMÔM��øÝ�_Ð-ð ð ð Ø�ðøøøåÐSÐSÐSÐSÕ4RÐSÑSÔSÑSÔSð àØ�NŠN˜D )¨YÐ7Ñ8Ô8Ð8Ð8ð	9ð €Ns   ¦A»AÁA'Á&A'c                  ó8   — t          t          ¦   «         ¦  «        S )z<Return True when any legacy Hermes gateway unit files exist.)r%   rž  r   r*   r(   Úhas_legacy_hermes_unitsr   @  s   € åÕ)Ñ+Ô+Ñ,Ô,Ð,r*   c                  ó
  — t          ¦   «         } | sdS t          d¦  «         | D ]"\  }}}|rdnd}t          d|› d|› d�¦  «         Œ#t          d¦  «         t          d	¦  «         t          d
¦  «         t          d¦  «         dS )z¾Warn about legacy Hermes gateway unit files if any are installed.

    Idempotent: prints nothing when no legacy units are detected. Safe to
    call from any status/install/setup path.
    Nz=Legacy Hermes gateway unit(s) detected from an older install:r´   rQ  z    ú  (ú scope)z<  These run alongside the current hermes-gateway service anduB     cause SIGTERM flap loops â€” both try to use the same bot token.z  Remove them with:z!    hermes gateway migrate-legacy)rž  r   r   )ÚlegacyrR  Úpathrœ  Úscopes        r(   Úprint_legacy_unit_warningr§  E  s¶   € õ 'Ñ(Ô(€FØð ØˆÝÐQÑRÔRÐRØ!'ð 3ð 3Ñˆˆd�IØ%Ð1��¨6ˆÝÐ1˜$Ð1Ð1 5Ð1Ð1Ð1Ñ2Ô2Ð2Ð2ÝÐMÑNÔNÐNÝÐSÑTÔTÐTÝÐ$Ñ%Ô%Ð%ÝÐ2Ñ3Ô3Ð3Ð3Ð3r*   ÚinteractiveÚdry_runc                 óN  — t          ¦   «         }|st          d¦  «         dg fS d„ |D ¦   «         }d„ |D ¦   «         }t          ¦   «          t          d¦  «         |D ]"\  }}}|rdnd}t          d|› d	|› d
�¦  «         Œ#t          ¦   «          |rt          d¦  «         dd„ |D ¦   «         fS | r-t          dd¦  «        st          d¦  «         dd„ |D ¦   «         fS d}	g }
|D ]¥\  }}	 t          d|gddd¬¦  «         t          d|gddd¬¦  «         |                     d¬¦  «         t          d|› �¦  «         |	dz  }	Œ^# t
          t          f$ r4}t          d|› d|› �¦  «         |
                     |¦  «         Y d}~Œžd}~ww xY w|r&	 t          dgddd¬¦  «         n# t          $ r Y nw xY w|�r/t          j	        ¦   «         dk    rJt          ¦   «          t          d¦  «         t          d¦  «         |D ]\  }}|
                     |¦  «         ŒnÎ|D ]¥\  }}	 t          d|gddd¬¦  «         t          d|gddd¬¦  «         |                     d¬¦  «         t          d|› �¦  «         |	dz  }	Œ^# t
          t          f$ r4}t          d|› d|› �¦  «         |
                     |¦  «         Y d}~Œžd}~ww xY w	 t          dgddd¬¦  «         n# t          $ r Y nw xY wt          ¦   «          |
r t          t          |
¦  «        › d �¦  «         nt          d!|	› d"�¦  «         |	|
fS )#uÅ  Stop, disable, and remove legacy Hermes gateway unit files.

    Iterates over whatever ``_find_legacy_hermes_units()`` returns â€” which is
    an explicit allowlist of legacy names (not a glob). Profile units and
    unrelated third-party services are never touched.

    Args:
        interactive: When True, prompt before removing. When False, remove
            without asking (used when another prompt has already confirmed,
            e.g. from the install flow).
        dry_run: When True, list what would be removed and return.

    Returns:
        ``(removed_count, remaining_paths)`` â€” remaining includes units we
        couldn't remove (typically system-scope when not running as root).
    z%No legacy Hermes gateway units found.r   c                 ó"   — g | ]\  }}}|°||f‘ŒS r   r   ©r–   Únr—   Úis_syss       r(   r  z.remove_legacy_hermes_units.<locals>.<listcomp>q  s'   € ÐBÐBÐB™\˜Q  6¸6ÐB�1�a�&ÐBÐBÐBr*   c                 ó"   — g | ]\  }}}|¯||f‘ŒS r   r   r¬  s       r(   r  z.remove_legacy_hermes_units.<locals>.<listcomp>r  s'   € Ð@Ð@Ð@™|˜q ! V¸Ð@�Q˜�FÐ@Ð@Ð@r*   z$Legacy Hermes gateway unit(s) found:r´   rQ  ú  r¢  r£  u   (dry-run â€” nothing removed)c                 ó   — g | ]\  }}}|‘Œ	S r   r   ©r–   r  r—   s      r(   r  z.remove_legacy_hermes_units.<locals>.<listcomp>}  ó   € Ð+Ð+Ð+™˜˜A˜q�1Ð+Ð+Ð+r*   zRemove these legacy units?Tz6Skipped. Run again with: hermes gateway migrate-legacyc                 ó   — g | ]\  }}}|‘Œ	S r   r   r²  s      r(   r  z.remove_legacy_hermes_units.<locals>.<listcomp>�  r³  r*   ÚstopFrî   rë   Údisablerê   )Ú
missing_oku     âœ“ Removed r`   u     âš  Could not remove r  Núdaemon-reloadz1System-scope legacy units require root to remove.z1  Re-run with: sudo hermes gateway migrate-legacyu5    legacy unit(s) still present â€” see messages above.zRemoved z legacy unit(s).)rž  rÜ   r   r½   Úunlinkrt   r¿   r‚   ri   Úgeteuidr   r   rU   r   )r¨  r©  r¤  Ú
user_unitsÚsystem_unitsrR  r¥  rœ  r¦  ÚremovedÚ	remainingÚer  s                r(   Úremove_legacy_hermes_unitsrÀ  X  ss  € õ( 'Ñ(Ô(€FØð ÝÐ5Ñ6Ô6Ð6Ø�"ˆuˆàBÐB¨VÐBÑBÔB€JØ@Ð@¨vÐ@Ñ@Ô@€Lå	�G„G€GÝ	Ð
0Ñ1Ô1Ð1Ø!'ð ,ð ,Ñˆˆd�IØ%Ð1��¨6ˆÝÐ*�4Ð*Ð*˜EÐ*Ð*Ð*Ñ+Ô+Ð+Ð+Ý	�G„G€Gàð ,ÝÐ-Ñ.Ô.Ð.ØÐ+Ð+ FÐ+Ñ+Ô+Ð+Ð+àð ,�=Ð)EÀtÑLÔLð ,ÝÐFÑGÔGÐGØÐ+Ð+ FÐ+Ñ+Ô+Ð+Ð+à€GØ€Ið !ð 	#ð 	#‰
ˆˆdð	#Ý˜F D˜>°%¸uÈbÐQÑQÔQÐQÝ˜I tÐ,°UÀ%ÐQSÐTÑTÔTÐTØ�KŠK 4ˆKÑ(Ô(Ð(ÝÐ) 4Ð)Ð)Ñ*Ô*Ð*Ø�q‰LˆGˆGøÝ�Ð&ð 	#ð 	#ð 	#ÝÐ7¨DÐ7Ð7°AÐ7Ð7Ñ8Ô8Ð8Ø×Ò˜TÑ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"øøøøð	#øøøð ð ð	Ý˜OÐ,°UÀ%ÐQSÐTÑTÔTÐTÐTøÝð 	ð 	ð 	ØˆDð	øøøð ñ ÝŒ:‰<Œ<˜1ÒÐÝ‰GŒGˆGÝÐMÑNÔNÐNÝÐJÑKÔKÐKØ'ð 'ð '‘��4Ø× Ò  Ñ&Ô&Ð&Ð&ð'ð +ð 	+ð 	+‘
��dð+Ý" F¨D >¸$ÀeÐUWÐXÑXÔXÐXÝ" I¨tÐ#4¸TÈÐXZÐ[Ñ[Ô[Ð[Ø—K’K¨4�KÑ0Ô0Ð0ÝÐ1¨4Ð1Ð1Ñ2Ô2Ð2Ø˜q‘L�G�GøÝ¥Ð.ð +ð +ð +ÝÐ?°DÐ?Ð?¸AÐ?Ð?Ñ@Ô@Ð@Ø×$Ò$ TÑ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*øøøøð+øøøðÝ Ð0¸ÀUÐTVÐWÑWÔWÐWÐWøÝð ð ð Ø�ðøøøõ 
�G„G€GØð <Ý�˜Y™œÐ^Ð^Ð^Ñ_Ô_Ð_Ð_åÐ: Ð:Ð:Ð:Ñ;Ô;Ð;à�IÐÐsV   Ã&AD>Ä>FÅ*E>Å>FÆ	F Æ
F+Æ*F+ÈAI2É2J7Ê*J2Ê2J7Ê;K Ë
KËKc                  ó2  — t          ¦   «         } t          | ¦  «        dk     rd S d                     | ¦  «        }t          d|› d�¦  «         t	          d¦  «         t	          d¦  «         t	          d¦  «         t	          d¦  «         t	          d	¦  «         d S )
NrD   z + z5Both user and system gateway services are installed (rr  zF  This is confusing and can make start/stop/status behavior ambiguous.zL  Default gateway commands target the user service unless you pass --system.z  Keep one of these:z    hermes gateway uninstallz*    sudo hermes gateway uninstall --system)rŒ  rU   r¥   r   r   )r‰  Úrendered_scopess     r(   Ú$print_systemd_scope_conflict_warningrÃ  º  s�   € Ý)Ñ+Ô+€FÝ
ˆ6�{„{�Q‚€Øˆà—j’j Ñ(Ô(€OÝÐ]È/Ð]Ð]Ð]Ñ^Ô^Ð^ÝÐWÑXÔXÐXÝÐ]Ñ^Ô^Ð^ÝÐ%Ñ&Ô&Ð&ÝÐ-Ñ.Ô.Ð.ÝÐ;Ñ<Ô<Ð<Ð<Ð<r*   Úactionc                 ó†   — t          j        ¦   «         dk    r)t          d| › d�¦  «         t          j        d¦  «         d S d S )Nr   zSystem gateway z! requires root. Re-run with sudo.r`   )ri   rº  rÜ   r  Úexit)rÄ  s    r(   Ú _require_root_for_system_servicerÇ  È  sF   € Ý	„z�|„|�qÒÐÝÐI ÐIÐIÐIÑJÔJÐJÝŒ�‰Œˆˆˆð Ðr*   Úrun_as_userc                 óD  — dd l }dd l}dd l}| pOt          j        d¦  «        p;t          j        d¦  «        p't          j        d¦  «        p|                     ¦   «                              ¦   «         }|st          d¦  «        ‚|dk    r| st          d¦  «        ‚|dk    rt          d¦  «         t          d	¦  «         	 | 
                    |¦  «        }n%# t          $ r}t          d
|› �¦  «        |‚d }~ww xY w|                     |j        ¦  «        j        }|||j        fS )Nr   Ú	SUDO_USERÚUSERÚLOGNAMEz@Could not determine which user the gateway service should run asÚrootztRefusing to install the gateway system service as root; pass --run-as-user root to override (e.g. in LXC containers)z*Installing gateway service to run as root.zV  This is fine for LXC/container environments but not recommended on bare-metal hosts.zUnknown user: )rs  ÚgrpÚpwdri   Úgetenvrt  rJ   rO   r   r   ÚgetpwnamÚKeyErrorÚgetgrgidÚpw_gidÚgr_nameÚpw_dir)rÈ  rs  rÎ  rÏ  rx  Ú	user_infor¿  Ú
group_names           r(   Ú_system_service_identityrÙ  Î  sY  € Ø€N€N€NØ€J€J€JØ€J€J€JàÐw�rœy¨Ñ5Ô5Ðw½¼À6Ñ9JÔ9JÐwÍbÌiÐXaÑNbÔNbÐwÐfm×fuÒfuÑfwÔfw×~Ò~ñ  Aô  A€HØð ]ÝÐ[Ñ\Ô\Ð\Ø�6ÒÐ +ÐÝð  Pñ  Qô  Qð  	QØ�6ÒÐÝÐBÑCÔCÐCÝÐkÑlÔlÐlð=Ø—L’L Ñ*Ô*ˆ	ˆ	øÝð =ð =ð =ÝÐ4¨(Ð4Ð4Ñ5Ô5¸1Ð<øøøøð=øøøð —’˜iÔ.Ñ/Ô/Ô7€JØ�Z Ô!1Ð1Ð1s   Â>C Ã
C6ÃC1Ã1C6r‹  c                 ó  — |                       ¦   «         sd S |                      d¬¦  «                             ¦   «         D ]K}|                     d¦  «        r4|                     dd¦  «        d                              ¦   «         }|pd c S ŒLd S )Nr”  ©r–  zUser=rË   r`   )r¼   rš  rK   r¢   rL   rJ   )r‹  rY   rÎ   s      r(   Ú_read_systemd_user_from_unitrÜ  å  s›   € Ø×ÒÑÔð Øˆtà×#Ò#¨WÐ#Ñ5Ô5×@Ò@ÑBÔBð !ð !ˆØ�?Š?˜7Ñ#Ô#ð 	!Ø—J’J˜s AÑ&Ô& qÔ)×/Ò/Ñ1Ô1ˆEØ�=˜DÐ Ð Ð ð	!ð ˆ4r*   c                  ó
  — t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        fD ]F} | rB|                      ¦   «         r.|                      ¦   «         dk    r|                      ¦   «         c S ŒGd S )NrÊ  rË  rÌ  rÍ  )ri   rÐ  rJ   )Ú	candidates    r(   Ú_default_system_service_userrß  ð  s   € Ý”i Ñ,Ô,­b¬i¸Ñ.?Ô.?ÅÄÈ9ÑAUÔAUÐVð %ð %ˆ	Øð 	%˜ŸšÑ*Ô*ð 	%¨y¯ªÑ/@Ô/@ÀFÒ/JÐ/JØ—?’?Ñ$Ô$Ð$Ð$Ð$øØˆ4r*   c                  óB   — t          dg d¢d¬¦  «        } ddd dœ|          S )Nz6  Choose how the gateway should run in the background:)zPUser service (no sudo; best for laptops/dev boxes; may need linger after logout)zGSystem service (starts on boot; requires sudo; still runs as your user)zSkip service install for nowr   ©rB  rQ  r´   )r   r`   rD   )r   )Úchoices    r(   Ú"prompt_linux_gateway_install_scoperã  ÷  sD   € ÝØ@ð	
ð 	
ð 	
ð
 ðñ ô €Fð ˜( tÐ,Ð,¨VÔ4Ð4r*   c                 óØ  — t          ¦   «         }|€dS |dk    r¾t          ¦   «         }t          j        ¦   «         dk    rFt	          d¦  «         |rt          d|› �¦  «         nt          d¦  «         t          d¦  «         |dfS |s;	 t          d
d¬¦  «        }|pd                     ¦   «         }|rnt          d¦  «         Œ:t          | d	|¬¦  «         |d	fS t          | d¬¦  «         |d	fS )N©NFr´   r   zY  System service install requires sudo, so Hermes can't create it from this user session.zG  After setup, run: sudo hermes gateway install --system --run-as-user zR  After setup, run: sudo hermes gateway install --system --run-as-user <your-user>z8  Then start it with: sudo hermes gateway start --systemFTz/  Run the system gateway service as which user?r‰   rá  z  Enter a username.©r  r´   rÈ  )r  r´   )
rã  rß  ri   rº  r   r   r   rJ   r   Úsystemd_install)r  r¦  rÈ  s      r(   Ú install_linux_gateway_from_setuprè    s-  € Ý.Ñ0Ô0€EØ€}Øˆ{à�ÒÐÝ2Ñ4Ô4ˆÝŒ:‰<Œ<˜1ÒÐÝÐuÑvÔvÐvØð qÝÐrÐepÐrÐrÑsÔsÐsÐsåÐoÑpÔpÐpÝÐQÑRÔRÐRØ˜%�<Ðàð 	3ð3Ý$Ð%VÐ`bÐcÑcÔc�Ø*Ð0¨b×7Ò7Ñ9Ô9�Øð ØÝÐ1Ñ2Ô2Ð2ð3õ 	˜e¨D¸kÐJÑJÔJÐJØ�dˆ{Ðå˜%¨Ð.Ñ.Ô.Ð.Ø�$ˆ;Ðr*   c                  óÔ  — t          ¦   «         rdS t          ¦   «         sdS t          j        d¦  «        sdS t	          j        d¦  «        pt	          j        d¦  «        } | sB	 ddl}|                     t	          j        ¦   «         ¦  «        j	        } n# t          $ r Y d	S w xY w	 t          j        dd
| ddgdddd¬¦  «        }n(# t          $ r}dt          |¦  «        fcY d}~S d}~ww xY w|j        dk    r0|j        p|j        p	d|j        › �                     ¦   «         }d|pdfS |j        pd                     ¦   «                              ¦   «         }|dv rdS |dv rdS |pd}dd|› �fS )zÝReturn systemd linger status for the current user.

    Returns:
        (True, "") when linger is enabled.
        (False, "") when linger is disabled.
        (None, detail) when the status could not be determined.
    )Nznot supported in Termux)Nznot supported on this platformrm  )Núloginctl not foundrË  rÌ  r   N)Nz could not determine current userz	show-userz--property=Lingerr@   TFr“   ro  rq  zloginctl query failedr‰   >   Ú1ÚyesÚtrue)Tr‰   >   Ú0ÚnoÚfalse)Fr‰   z<empty>zunexpected loginctl output: )rù   rû   r-  r.  ri   rÐ  rÏ  Úgetpwuidr[  Úpw_namer±   rG   rH   r0   rT   rw  rI   rJ   rï   )rx  rÏ  rX   r¿  r{  rÎ   r  s          r(   ru  ru  #  sÜ  € õ �{„{ð /Ø.Ð.Ý‰:Œ:ð 6Ø5Ð5åŒ<˜
Ñ#Ô#ð *Ø)Ð)åŒy˜Ñ Ô Ð8¥B¤I¨iÑ$8Ô$8€HØð <ð	<ØˆJˆJˆJØ—|’|¥B¤I¡K¤KÑ0Ô0Ô8ˆHˆHøÝð 	<ð 	<ð 	<Ø;Ð;Ð;ð	<øøøð	Ý”Ø˜ hÐ0CÀYÐOØØØØð
ñ 
ô 
ˆˆøõ ð ð ð Ø•S˜‘V”Vˆ|ÐÐÐÐÐÐøøøøðøøøð Ô˜AÒÐØ”-ÐO 6¤=ÐOÐ4O¸FÔ<MÐ4OÐ4O×VÒVÑXÔXˆØ�VÐ6Ð6Ð6Ð6àŒ]Ð ˜b×'Ò'Ñ)Ô)×/Ò/Ñ1Ô1€EØÐ$Ð$Ð$ØˆxØÐ$Ð$Ð$ØˆyàÐ!˜	€HØÐ:°Ð:Ð:Ð:Ð:s0   Á"/B Â
B ÂB Â$C Ã
C(ÃC#ÃC(Ã#C(c                  óü   — t          ¦   «         \  } }| du rt          d¦  «         d
S | du r t          d¦  «         t          d¦  «         d
S t          d|› d�¦  «         t          d¦  «         t          d	¦  «         d
S )z@Print the current linger status and the fix when it is disabled.Tõ7   âœ“ Systemd linger is enabled (service survives logout)FõB   âš  Systemd linger is disabled (gateway may stop when you log out)ú(  Run: sudo loginctl enable-linger $USERu%   âš  Could not verify systemd linger (rÓ   z>  If you want the gateway user service to survive logout, run:z#  sudo loginctl enable-linger $USERN)ru  rÜ   )ry  rz  s     r(   Úprint_systemd_linger_guidancer÷  T  sŸ   € å$=Ñ$?Ô$?Ñ!€N�MØ˜ÐÐÝÐGÑHÔHÐHÐHÐHØ	˜5Ð	 Ð	 ÝÐRÑSÔSÐSÝÐ8Ñ9Ô9Ð9Ð9Ð9åÐF°mÐFÐFÐFÑGÔGÐGÝÐNÑOÔOÐOÝÐ3Ñ4Ô4Ð4Ð4Ð4r*   c                  óz   — ddl } t          |                      t          j        ¦   «         ¦  «        j        ¦  «        S )zÍReturn the real macOS user home for launchd artifacts.

    Profile-mode Hermes often sets ``HOME`` to a profile-scoped directory, but
    launchd user agents still live under the actual account home.
    r   N)rÏ  r   rñ  ri   r[  rÖ  )rÏ  s    r(   Ú_launchd_user_homerù  a  s0   € ð €J€J€Jå�—’�RœY™[œ[Ñ)Ô)Ô0Ñ1Ô1Ð1r*   c                  ód   — t          ¦   «         } | rd| › �nd}t          ¦   «         dz  dz  |› d�z  S )uÙ   Return the launchd plist path, scoped per profile.

    Default ``~/.hermes`` â†’ ``ai.hermes.gateway.plist`` (backward compatible).
    Profile ``~/.hermes/profiles/coder`` â†’ ``ai.hermes.gateway-coder.plist``.
    úai.hermes.gateway-úai.hermes.gatewayÚLibraryÚLaunchAgentsz.plist)rE  rù  )rL  rR  s     r(   rô   rô   l  sI   € õ ÑÔ€FØ,2ÐKÐ( Ð(Ð(Ð(Ð8K€DÝÑÔ )Ñ+¨nÑ<À$¸¸¸ÑNÐNr*   c                  ór  — t           j        t           j        k    r/t          t           j        ¦  «        } |                      ¦   «         r| S t
          j                             d¦  «        }|r%t          |¦  «        } |                      ¦   «         r| S dD ]$}t          |z  } |                      ¦   «         r| c S Œ%dS )ab  Detect the active virtualenv directory.

    Checks ``sys.prefix`` first (works regardless of the directory name),
    then ``VIRTUAL_ENV`` env var (covers uv-managed environments where
    sys.prefix == sys.base_prefix), then falls back to probing common
    directory names under PROJECT_ROOT.
    Returns ``None`` when no virtualenv can be found.
    ÚVIRTUAL_ENV)z.venvÚvenvN)	r  ÚprefixÚbase_prefixr   Úis_dirri   rZ  r’   ÚPROJECT_ROOT)r  Ú_virtual_envrÞ  s      r(   Ú_detect_venv_dirr  v  s¶   € õ „z•S”_Ò$Ð$Ý•C”JÑÔˆØ�;Š;‰=Œ=ð 	ØˆKõ
 ”:—>’> -Ñ0Ô0€LØð Ý�LÑ!Ô!ˆØ�;Š;‰=Œ=ð 	ØˆKð 'ð ð ˆ	Ý˜iÑ'ˆØ�;Š;‰=Œ=ð 	ØˆKˆKˆKð	ð ˆ4r*   c                  ó¾   — t          ¦   «         } | �Bt          ¦   «         r	| dz  dz  }n| dz  dz  }|                     ¦   «         rt          |¦  «        S t          j        S )NÚScriptsz
python.exeÚbinÚpython)r  r¡   r¼   r0   r  Ú
executable)r  Úvenv_pythons     r(   Úget_python_pathr  —  sh   € ÝÑÔ€DØÐÝ‰<Œ<ð 	2Ø Ñ*¨\Ñ9ˆKˆKà ™,¨Ñ1ˆKØ×ÒÑÔð 	$Ý�{Ñ#Ô#Ð#ÝŒ>Ðr*   rA  Úpath_entriesc                 óÄ   ‡— t          | dz  dz  ¦  «        t          | dz  dz  ¦  «        t          | dz  dz  ¦  «        t          | dz  dz  ¦  «        g}ˆfd„|D ¦   «         S )zKReturn user-local bin dirs that exist and aren't already in *path_entries*.z.localr
  z.cargoÚgoz.npm-globalc                 ó^   •— g | ])}|‰v¯t          |¦  «                             ¦   «         ¯'|‘Œ*S r   )r   r¼   )r–   r—   r  s     €r(   r  z+_build_user_local_paths.<locals>.<listcomp>¯  s8   ø€ ÐPÐPÐP�! Q¨lÐ%:Ð%:½tÀA¹w¼w¿~º~Ñ?OÔ?OÐ%:ˆAÐ%:Ð%:Ð%:r*   r  )rA  r  Ú
candidatess    ` r(   Ú_build_user_local_pathsr  §  sz   ø€ õ 	ˆD�8‰O˜eÑ#Ñ$Ô$ÝˆD�8‰O˜eÑ#Ñ$Ô$ÝˆD�4‰K˜%ÑÑ Ô ÝˆD�=Ñ  5Ñ(Ñ)Ô)ð	€Jð QÐPÐPÐP�zÐPÑPÔPÐPr*   r¥  Útarget_home_dirc                 ó  — t          j        ¦   «         }t          | ¦  «                             ¦   «         }	 |                     |¦  «        }t	          t          |¦  «        |z  ¦  «        S # t
          $ r t	          |¦  «        cY S w xY w)aZ  Remap *path* from the current user's home to *target_home_dir*.

    If *path* lives under ``Path.home()`` the corresponding prefix is swapped
    to *target_home_dir*; otherwise the path is returned unchanged.

      /root/.hermes/hermes-agent  -> /home/alice/.hermes/hermes-agent
      /opt/hermes                 -> /opt/hermes  (kept as-is)

    Note: this function intentionally does NOT resolve symlinks. A venv's
    ``bin/python`` is typically a symlink to the base interpreter (e.g. a
    uv-managed CPython at ``~/.local/share/uv/python/.../python3.11``);
    resolving that symlink swaps the unit's ``ExecStart`` to a bare Python
    that has none of the venv's site-packages, so the service crashes on
    the first ``import``. Keep the symlinked path so the venv activates
    its own environment. Lexical expansion only via ``expanduser``.
    )r   rA  Ú
expanduserr<  r0   rO   )r¥  r  r�   r—   Úrelatives        r(   Ú_remap_path_for_userr  ²  s�   € õ" ”9‘;”;€LÝˆT‰
Œ
×ÒÑÔ€AðØ—=’= Ñ.Ô.ˆÝ•4˜Ñ(Ô(¨8Ñ3Ñ4Ô4Ð4øÝð ð ð Ý�1‰vŒvˆˆˆðøøøs   ¶3A* Á*BÂBc                 ón  — t          ¦   «                              ¦   «         }t          j        ¦   «         dz                       ¦   «         }t          | ¦  «        dz  }||k    rt	          |¦  «        S 	 |                     |¦  «        }t	          ||z  ¦  «        S # t          $ r t	          |¦  «        cY S w xY w)uÂ  Remap the current HERMES_HOME to the equivalent under a target user's home.

    When installing a system service via sudo, get_hermes_home() resolves to
    root's home.  This translates it to the target user's equivalent path:
      /root/.hermes                    â†’ /home/alice/.hermes
      /root/.hermes/profiles/coder     â†’ /home/alice/.hermes/profiles/coder
      /opt/custom-hermes               â†’ /opt/custom-hermes  (kept as-is)
    z.hermes)r
   rŸ   r   rA  r0   r<  rO   )r  Úcurrent_hermesÚcurrent_defaultÚtarget_defaultr  s        r(   Ú_hermes_home_for_target_userr  Ì  s¾   € õ %Ñ&Ô&×.Ò.Ñ0Ô0€NÝ”y‘{”{ YÑ.×7Ò7Ñ9Ô9€OÝ˜/Ñ*Ô*¨YÑ6€Nð ˜Ò(Ð(Ý�>Ñ"Ô"Ð"ð#Ø!×-Ò-¨oÑ>Ô>ˆÝ�> HÑ,Ñ-Ô-Ð-øÝð #ð #ð #å�>Ñ"Ô"Ð"Ð"Ð"ð#øøøs   Á1&B ÂB4Â3B4c                 ó^  ‡— t          ¦   «         }t          t          ¦  «        }t          ¦   «         }|rt          |¦  «        nt          t          dz  ¦  «        }|rt          |dz  ¦  «        nt          t          dz  dz  ¦  «        }t          t          dz  dz  ¦  «        }||g}t	          j        d¦  «        }	|	rLt          t          |	¦  «                             ¦   «         j        ¦  «        }
|
|vr| 	                    |
¦  «         g d¢}t          t          ¦   «         pd¦  «        }t          d|¦  «        d	z   }| �r't          |¦  «        \  }}Št          ‰¦  «        }t          |¦  «        }t!          |‰¦  «        }t!          |‰¦  «        }t!          |‰¦  «        }t!          |‰¦  «        }t!          |‰¦  «        }ˆfd
„|D ¦   «         }|                     t%          t          ‰¦  «        |¦  «        ¦  «         |                     |¦  «         d                     |¦  «        }dt(          › d|› d|› d|› d|rd|› �nd› d|› d‰› d|› d|› d|› d|› d|› dt*          › d|› d�S t          t-          ¦   «                              ¦   «         ¦  «        }t          |¦  «        }|                     t%          t          j        ¦   «         |¦  «        ¦  «         |                     |¦  «         d                     |¦  «        }dt(          › d|› d|rd|› �nd› d|› d|› d|› d|› dt*          › d|› d�S ) Nr  r
  Únode_modulesú.binÚnode)z/usr/local/sbinz/usr/local/binz	/usr/sbinz/usr/binz/sbinz/binr   é<   rê   c                 ó0   •— g | ]}t          |‰¦  «        ‘ŒS r   )r  )r–   r—   Úhome_dirs     €r(   r  z)generate_systemd_unit.<locals>.<listcomp>  s$   ø€ ÐPÐPÐP¸aÕ,¨Q°Ñ9Ô9ÐPÐPÐPr*   ú:z[Unit]
Description=z�
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=600
StartLimitBurst=5

[Service]
Type=simple
User=z
Group=z
ExecStart=z -m hermes_cli.mainrœ   r‰   z( gateway run --replace
WorkingDirectory=z
Environment="HOME=z"
Environment="USER=z"
Environment="LOGNAME=z"
Environment="PATH=z"
Environment="VIRTUAL_ENV=z"
Environment="HERMES_HOME=z:"
Restart=on-failure
RestartSec=30
RestartForceExitStatus=zV
KillMode=mixed
KillSignal=SIGTERM
ExecReload=/bin/kill -USR1 $MAINPID
TimeoutStopSec=zT
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
zc
After=network.target
StartLimitIntervalSec=600
StartLimitBurst=5

[Service]
Type=simple
ExecStart=z
Environment="PATH=zQ
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target
)r  r0   r  r  r-  r.  r   rŸ   Úparentr‚   r3   Ú_get_restart_drain_timeoutr{   rÙ  r  r    r  Úextendr  r¥   ÚSERVICE_DESCRIPTIONr   r
   rA  )r´   rÈ  Úpython_pathÚworking_dirÚdetected_venvÚvenv_dirÚvenv_binÚnode_binr  Úresolved_nodeÚresolved_node_dirÚcommon_bin_pathsÚ_drain_timeoutÚrestart_timeoutrx  rØ  rF  Úprofile_argÚ	sane_pathr%  s                      @r(   Úgenerate_systemd_unitr8  æ  s2  ø€ Ý!Ñ#Ô#€KÝ•lÑ#Ô#€KÝ$Ñ&Ô&€MØ%2ÐR�s�=Ñ!Ô!Ð!½½LÈ6Ñ<QÑ8RÔ8R€HØ-:Ðb�s�= 5Ñ(Ñ)Ô)Ð)ÅÅLÐSYÑDYÐ\aÑDaÑ@bÔ@b€HÝ•< .Ñ0°6Ñ9Ñ:Ô:€Hà˜hÐ'€LÝ”L Ñ(Ô(€MØð 3Ý¥ ]Ñ 3Ô 3× ;Ò ;Ñ =Ô =Ô DÑEÔEÐØ LÐ0Ð0Ø×ÒÐ 1Ñ2Ô2Ð2àfÐfÐfÐõ Õ3Ñ5Ô5Ð:¸Ñ;Ô;€NÝ˜"˜nÑ-Ô-°Ñ2€Oàñ /Ý)AÀ+Ñ)NÔ)NÑ&ˆ�*˜hÝ2°8Ñ<Ô<ˆÝ" ;Ñ/Ô/ˆõ +¨;¸ÑAÔAˆÝ*¨;¸ÑAÔAˆÝ'¨°(Ñ;Ô;ˆÝ'¨°(Ñ;Ô;ˆÝ'¨°(Ñ;Ô;ˆØPÐPÐPÐPÀ<ÐPÑPÔPˆØ×ÒÕ3µD¸±N´NÀLÑQÔQÑRÔRÐRØ×ÒÐ,Ñ-Ô-Ð-Ø—H’H˜\Ñ*Ô*ˆ	ðÝ ðð ð ðð ð ðð ð ðð ð ALÐ+SÐ+<¨{Ð+<Ð+<Ð+<ÐQSðð ð ðð ð ðð ð ðð ð ðð ð  ð!ð ð" #ð#ð ð$ &ð%ð õ* :ð+ð ð2  ð3ð ð ð 	õB •oÑ'Ô'×/Ò/Ñ1Ô1Ñ2Ô2€KÝ˜{Ñ+Ô+€KØ×ÒÕ/µ´	±´¸\ÑJÔJÑKÔKÐKØ×ÒÐ(Ñ)Ô)Ð)Ø—’˜Ñ&Ô&€IðÝ ðð ð ðð ð ALÐ+SÐ+<¨{Ð+<Ð+<Ð+<ÐQSðð ð ðð ð ðð ð #ðð ð &ðð õ :ðð ð&  ð'ð ð ð r*   r<   c                 óˆ   — d                      d„ |                      ¦   «                              ¦   «         D ¦   «         ¦  «        S )Nr”   c              3   ó>   K  — | ]}|                      ¦   «         V — Œd S r$   )Úrstrip)r–   rY   s     r(   r™   z0_normalize_service_definition.<locals>.<genexpr>Q  s*   è è € ÐIÐI t�T—[’[‘]”]ÐIÐIÐIÐIÐIÐIr*   )r¥   rJ   rK   )r<   s    r(   Ú_normalize_service_definitionr<  P  s7   € Ø�9Š9ÐIÐI¨t¯zªz©|¬|×/FÒ/FÑ/HÔ/HÐIÑIÔIÑIÔIÐIr*   c                 ód   — ddl }t          | ¦  «        }|                     dd||j        ¬¦  «        S )a`  Normalize launchd plist text for staleness checks.

    The generated plist intentionally captures a broad PATH assembled from the
    invoking shell so user-installed tools remain reachable under launchd.
    That makes raw text comparison unstable across shells, so ignore the PATH
    payload when deciding whether the installed plist is stale.
    r   Nz,(<key>PATH</key>\s*<string>)(.*?)(</string>)z\1__HERMES_PATH__\3)Úflags)r;  r<  ÚsubÚS)r<   r;  Ú
normalizeds      r(   Ú'_normalize_launchd_plist_for_comparisonrB  T  sC   € ð €I€I€Iå.¨tÑ4Ô4€JØ�6Š6Ø7ØØØŒdð	 ñ ô ð r*   c                 ó  — t          | ¬¦  «        }|                     ¦   «         sdS |                     d¬¦  «        }| rt          |¦  «        nd }t	          | |¬¦  «        }t          |¦  «        t          |¦  «        k    S )Nr¶   Fr”  rÛ  ©r´   rÈ  )r»   r¼   rš  rÜ  r8  r<  )r´   r‹  Ú	installedÚexpected_userÚexpecteds        r(   Úsystemd_unit_is_currentrH  g  sˆ   € Ý%¨VÐ4Ñ4Ô4€IØ×ÒÑÔð Øˆuà×#Ò#¨WÐ#Ñ5Ô5€IØ?EÐOÕ0°Ñ;Ô;Ð;È4€MÝ$¨FÀÐNÑNÔN€HÝ(¨Ñ3Ô3Õ7TÐU]Ñ7^Ô7^Ò^Ð^r*   c                 óL  — t          | ¬¦  «        }|                     ¦   «         rt          | ¬¦  «        rdS | rt          |¦  «        nd}|                     t          | |¬¦  «        d¬¦  «         t          dg| dd	¬
¦  «         t          dt          | ¦  «        › d�¦  «         dS )zMRewrite the installed systemd unit when the generated definition has changed.r¶   FNrD  r”  rÛ  r¸  Trê   rë   u   â†» Updated gateway z7 service definition to match the current Hermes install)	r»   r¼   rH  rÜ  Ú
write_textr8  r½   rÜ   rÚ   )r´   r‹  rF  s      r(   Úrefresh_systemd_unit_if_neededrK  s  sÀ   € å%¨VÐ4Ñ4Ô4€IØ×ÒÑÔð Õ!8ÀÐ!GÑ!GÔ!Gð Øˆuà?EÐOÕ0°Ñ;Ô;Ð;È4€MØ×ÒÕ.°fÈ-ÐXÑXÔXÐcjÐÑkÔkÐkÝ�OÐ$¨V¸4ÈÐLÑLÔLÐLÝ	Ð
vÕ!5°fÑ!=Ô!=Ð
vÐ
vÐ
vÑwÔwÐwØˆ4r*   r{  c                 óZ  — t          ¦   «          t          d¦  «         |rt          d|› �¦  «         t          ¦   «          t          d¦  «         t          d| › �¦  «         t          ¦   «          t          d¦  «         t          dt          ¦   «         › d�¦  «         t          ¦   «          d S )NuI   âš  Linger not enabled â€” gateway may stop when you close this terminal.z  Auto-enable failed: z1  On headless servers (VPS, cloud instances) run:z     sudo loginctl enable-linger ú  Then restart the gateway:z    systemctl --user restart r>   )rÜ   r¾   )rx  r{  s     r(   Ú_print_linger_enable_warningrN  �  s®   € Ý	�G„G€GÝ	Ð
UÑVÔVÐVØð 1ÝÐ/ vÐ/Ð/Ñ0Ô0Ð0Ý	�G„G€GÝ	Ð
=Ñ>Ô>Ð>Ý	Ð
7¨XÐ
7Ð
7Ñ8Ô8Ð8Ý	�G„G€GÝ	Ð
'Ñ(Ô(Ð(Ý	Ð
FÕ*:Ñ*<Ô*<Ð
FÐ
FÐ
FÑGÔGÐGÝ	�G„G€G€G€Gr*   c                  óð  — t          ¦   «         st          ¦   «         sdS ddl} |                      ¦   «         }t	          d|› �¦  «        }|                     ¦   «         rt          d¦  «         dS t          ¦   «         \  }}|du rt          d¦  «         dS t          j	        d¦  «        st          ||pd¦  «         dS t          d¦  «         	 t          j        dd	|gddd
d¬¦  «        }n5# t          $ r(}t          |t          |¦  «        ¦  «         Y d}~dS d}~ww xY w|j        dk    rt          d¦  «         dS |j        p|j        p	d|j        › �                     ¦   «         }t          ||p|¦  «         dS )z@Enable linger when possible so the user gateway survives logout.Nr   z/var/lib/systemd/linger/rô  Trm  rê  z5Enabling linger so the gateway survives SSH logout...rn  Frê   ro  u8   âœ“ Linger enabled â€” gateway will persist after logoutrq  )rù   rû   rs  rt  r   r¼   rÜ   ru  r-  r.  rN  rG   rH   r±   r0   rT   rw  rI   rJ   )rs  rx  Úlinger_filery  rz  rX   r¿  r{  s           r(   Ú_ensure_linger_enabledrQ  �  sÀ  € å�{„{ð �(™*œ*ð Øˆà€N€N€Nà�ŠÑ Ô €HÝÐ<°(Ð<Ð<Ñ=Ô=€KØ×ÒÑÔð ÝÐGÑHÔHÐHØˆå$=Ñ$?Ô$?Ñ!€N�MØ˜ÐÐÝÐGÑHÔHÐHØˆåŒ<˜
Ñ#Ô#ð Ý$ X¨}Ð/TÐ@TÑUÔUÐUØˆå	Ð
AÑBÔBÐBð
Ý”Ø˜¨(Ð3ØØØØð
ñ 
ô 
ˆˆøõ ð ð ð Ý$ X­s°1©v¬vÑ6Ô6Ð6Øˆˆˆˆˆøøøøðøøøð Ô˜AÒÐÝÐHÑIÔIÐIØˆàŒmÐK˜vœ}ÐKÐ0K¸Ô8IÐ0KÐ0K×RÒRÑTÔT€FÝ  ¨6Ð+B°]ÑCÔCÐCÐCÐCs   ÃC) Ã)
DÃ3DÄDc                 ó”   — | rdS t          d¬¦  «                             ¦   «         o"t          d¬¦  «                             ¦   «          S )NTr¶   F)r»   r¼   r¶   s    r(   rº   rº   »  sM   € Øð ØˆtÝ ¨Ð-Ñ-Ô-×4Ò4Ñ6Ô6ÐkÕ?TÐ\aÐ?bÑ?bÔ?b×?iÒ?iÑ?kÔ?kÐ;kÐkr*   c                  ó8  — t          j        dd¦  «                             ¦   «         } | sct          ¦   «         }t	          |t
          ¦  «        r|                     di ¦  «        ni }t          |                     dt          ¦  «        ¦  «        } t          | ¦  «        S )z?Return the configured gateway restart drain timeout in seconds.ÚHERMES_RESTART_DRAIN_TIMEOUTr‰   ÚagentÚrestart_drain_timeout)
ri   rÐ  rJ   r   Ú
isinstanceÚdictr’   r0   r   r   )rd   ÚcfgÚ	agent_cfgs      r(   r(  r(  Á  s�   € å
Œ)Ð2°BÑ
7Ô
7×
=Ò
=Ñ
?Ô
?€CØð 
ÝÑÔˆÝ,6°s½DÑ,AÔ,AÐI�C—G’G˜G RÑ(Ô(Ð(Àrˆ	ÝØ�MŠMØ'Õ)Nñô ñ
ô 
ˆõ
 ' sÑ+Ô+Ð+r*   c                 ó  — |rt          d¦  «         t          ¦   «         rXt          ¦   «          t          ¦   «          t          ¦   «          t	          dd¦  «        rt          d¬¦  «         t          ¦   «          t          |¬¦  «        }|rdnd}|                     ¦   «         r¼| sºt          |¬¦  «        s‡t          d	t          |¦  «        › d
|› �¦  «         t          |¬¦  «         t          dt          ¦   «         g|dd¬¦  «         t          dt          |¦  «                             ¦   «         › d�¦  «         d S t          d|› �¦  «         t          d¦  «         d S |j                             dd¬¦  «         t          dt          |¦  «        › d|› �¦  «         |                     t#          ||¬¦  «        d¬¦  «         t          dg|dd¬¦  «         t          dt          ¦   «         g|dd¬¦  «         t          ¦   «          t          dt          |¦  «                             ¦   «         › d�¦  «         t          ¦   «          t          d¦  «         t          d|rdnd› d|› d�¦  «         t          d|rdnd› d|› d �¦  «         t          d|rd!nd"› d#t          ¦   «         › d$�¦  «         t          ¦   «          |r$t%          |¦  «        }|rt          d%|› �¦  «         nt'          ¦   «          t)          ¦   «          t          ¦   «          d S )&NÚinstallz,Remove the legacy unit(s) before installing?TF)r¨  r¶   ú	 --systemr‰   u   â†» Repairing outdated z systemd service at: Úenablerê   rë   rÒ   z service definition updatedúService already installed at: úUse --force to reinstall©ÚparentsÚexist_okzInstalling z systemd service to: rD  r”  rÛ  r¸  z service installed and enabled!úNext steps:r°  rØ   úhermes gateway startz!              # Start the servicezhermes gateway statusz             # Check statusr‚  zjournalctl --userz -u z -f  # View logsúConfigured to run as: )rÇ  r   rÜ   r§  r   rÀ  r»   r¼   rH  rÚ   rK  r½   r¾   rÛ   r'  ÚmkdirrJ  r8  rÜ  rQ  rÃ  )r  r´   rÈ  r‹  Ú
scope_flagÚconfigured_users         r(   rç  rç  Ï  sg  € Øð 4Ý(¨Ñ3Ô3Ð3õ Ñ Ô ð Ý‰ŒˆÝ!Ñ#Ô#Ð#Ý‰ŒˆÝÐGÈÑNÔNð 	Ý&°5Ð9Ñ9Ô9Ð9Ý‰GŒGˆGå%¨VÐ4Ñ4Ô4€IØ &Ð.��¨B€Jà×ÒÑÔð 	 %ð 	Ý&¨fÐ5Ñ5Ô5ð 	ÝÐjÕ,@ÀÑ,HÔ,HÐjÐjÐ_hÐjÐjÑkÔkÐkÝ*°&Ð9Ñ9Ô9Ð9Ý˜HÕ&6Ñ&8Ô&8Ð9À&ÐPTÐ^`ÐaÑaÔaÐaÝÐ_Õ-¨fÑ5Ô5×@Ò@ÑBÔBÐ_Ð_Ð_Ñ`Ô`Ð`ØˆFÝÐ:¨yÐ:Ð:Ñ;Ô;Ð;ÝÐ(Ñ)Ô)Ð)ØˆàÔ×Ò 4°$ÐÑ7Ô7Ð7Ý	Ð
VÕ,¨VÑ4Ô4Ð
VÐ
VÈ9Ð
VÐ
VÑWÔWÐWØ×ÒÕ.°fÈ+ÐVÑVÔVÐahÐÑiÔiÐiå�OÐ$¨V¸4ÈÐLÑLÔLÐLÝ�HÕ.Ñ0Ô0Ð1¸&ÈÐVXÐYÑYÔYÐYå	�G„G€GÝ	Ð
[Õ% fÑ-Ô-×8Ò8Ñ:Ô:Ð
[Ð
[Ð
[Ñ\Ô\Ð\Ý	�G„G€GÝ	ˆ-ÑÔÐÝ	Ð
k˜&Ð(ˆwˆw bÐ
kÐ
k¸jÐ
kÐ
kÐ
kÑlÔlÐlÝ	Ð
f˜&Ð(ˆwˆw bÐ
fÐ
f¸zÐ
fÐ
fÐ
fÑgÔgÐgÝ	Ð
h˜vÐ>ˆ|ˆ|Ð+>Ð
hÐ
hÕDTÑDVÔDVÐ
hÐ
hÐ
hÑiÔiÐiÝ	�G„G€Gàð !Ý6°yÑAÔAˆØð 	>ÝÐ<¨?Ð<Ð<Ñ=Ô=Ð=øåÑ Ô Ð å(Ñ*Ô*Ð*ÝÑÔÐÐÐr*   c                 óê  — t          | ¦  «        } | rt          d¦  «         t          dt          ¦   «         g| dd¬¦  «         t          dt          ¦   «         g| dd¬¦  «         t	          | ¬¦  «        }|                     ¦   «         r&|                     ¦   «          t          d	|› �¦  «         t          d
g| dd¬¦  «         t          dt          | ¦  «         	                    ¦   «         › d�¦  «         d S )NÚ	uninstallrµ  Frî   rë   r¶  rê   r¶   õ   âœ“ Removed r¸  TrÒ   z service uninstalled)
rº   rÇ  r½   r¾   r»   r¼   r¹  rÜ   rÚ   rÛ   )r´   r‹  s     r(   Úsystemd_uninstallrm  	  s	  € Ý" 6Ñ*Ô*€FØð 6Ý(¨Ñ5Ô5Ð5å�FÕ,Ñ.Ô.Ð/¸ÀeÐUWÐXÑXÔXÐXÝ�IÕ/Ñ1Ô1Ð2¸6ÈÐXZÐ[Ñ[Ô[Ð[å%¨VÐ4Ñ4Ô4€IØ×ÒÑÔð *Ø×ÒÑÔÐÝÐ(˜YÐ(Ð(Ñ)Ô)Ð)å�OÐ$¨V¸4ÈÐLÑLÔLÐLÝ	Ð
PÕ% fÑ-Ô-×8Ò8Ñ:Ô:Ð
PÐ
PÐ
PÑQÔQÐQÐQÐQr*   c                 ó*  — t          | ¦  «        } | rt          d¦  «         nt          ¦   «          t          | ¬¦  «         t	          dt          ¦   «         g| dd¬¦  «         t          dt          | ¦  «                             ¦   «         › d�¦  «         d S )Nrí   r¶   Trê   rë   rÒ   z service started)	rº   rÇ  r|  rK  r½   r¾   rÜ   rÚ   rÛ   r¶   s    r(   Úsystemd_startro    s    € Ý" 6Ñ*Ô*€FØð "Ý(¨Ñ1Ô1Ð1Ð1õ
 	 Ñ!Ô!Ð!Ý"¨&Ð1Ñ1Ô1Ð1Ý�GÕ-Ñ/Ô/Ð0¸ÀtÐUWÐXÑXÔXÐXÝ	Ð
LÕ% fÑ-Ô-×8Ò8Ñ:Ô:Ð
LÐ
LÐ
LÑMÔMÐMÐMÐMr*   c                 óì   — t          | ¦  «        } | rt          d¦  «         t          dt          ¦   «         g| dd¬¦  «         t	          dt          | ¦  «                             ¦   «         › d�¦  «         d S )Nrµ  Trî   rë   rÒ   z service stopped)rº   rÇ  r½   r¾   rÜ   rÚ   rÛ   r¶   s    r(   Úsystemd_stoprq  )  s~   € Ý" 6Ñ*Ô*€FØð 1Ý(¨Ñ0Ô0Ð0Ý�FÕ,Ñ.Ô.Ð/¸ÀdÐTVÐWÑWÔWÐWÝ	Ð
LÕ% fÑ-Ô-×8Ò8Ñ:Ô:Ð
LÐ
LÐ
LÑMÔMÐMÐMÐMr*   c                 ó  — t          | ¦  «        } | rt          d¦  «         nt          ¦   «          t          | ¬¦  «         ddlm}  |¦   «         }|��0t          |¦  «        �r dd l}t          | ¦  «         	                    ¦   «         }t          ¦   «         }t          d|› d�¦  «         |                     ¦   «         dz   }|                     ¦   «         |k     r[	 t          j        |d¦  «         |                     d¦  «         n# t          t           f$ r Y n/w xY w|                     ¦   «         |k     °[t          d	|› d
�¦  «         t#          d|g| dd¬¦  «         t#          d|g| dd¬¦  «         t%          | |¬¦  «         d S t'          | |¬¦  «        rd S t#          dt          ¦   «         g| dd¬¦  «         t#          dt          ¦   «         g| dd¬¦  «         t          dt          | ¦  «         	                    ¦   «         › d�¦  «         d S )NÚrestartr¶   r   r­   u   â�³ z  service draining active work...rî   r`   u   âš  Old process (PID z) still alive after 90sré   Frê   rë   rí   rç   zreload-or-restartTrÒ   rÔ   )rº   rÇ  r|  rK  r°   r®   ru   ry   rÚ   rÛ   r¾   rÜ   ri   rq   r|   rr   rs   r½   râ   rò   )r´   r®   r\   ry   rÝ   r[   r~   s          r(   Úsystemd_restartrt  2  sr  € Ý" 6Ñ*Ô*€FØð "Ý(¨Ñ3Ô3Ð3Ð3åÑ!Ô!Ð!Ý"¨&Ð1Ñ1Ô1Ð1Ø.Ð.Ð.Ð.Ð.Ð.à
ˆ/Ñ
Ô
€CØ
�Õ8¸Ñ=Ô=�ØˆˆˆÝ*¨6Ñ2Ô2×=Ò=Ñ?Ô?ˆÝÑ Ô ˆõ 	ÐB�[ÐBÐBÐBÑCÔCÐCØ—9’9‘;”; Ñ#ˆØ�iŠi‰kŒk˜HÒ$Ð$ðÝ”˜˜Q‘”�Ø—
’
˜1‘”��øÝ&­Ð8ð ð ð Ø�ðøøøð	 �iŠi‰kŒk˜HÒ$Ð$õ ÐF¨#ÐFÐFÐFÑGÔGÐGõ 	Ø˜SÐ!ØØØð		
ñ 	
ô 	
ð 	
õ 	Ø�cˆNØØØð		
ñ 	
ô 	
ð 	
õ 	*°ÀcÐJÑJÔJÐJØˆå'¨vÀCÐHÑHÔHð ØˆåØ	Õ)Ñ+Ô+Ð,ØØØð	ñ ô ð õ Ð'Õ)9Ñ);Ô);Ð<ÀVÐSWÐacÐdÑdÔdÐdÝ	Ð
NÕ% fÑ-Ô-×8Ò8Ñ:Ô:Ð
NÐ
NÐ
NÑOÔOÐOÐOÐOs   Ã*D ÄDÄDÚdeepÚfullc           
      óx  — t          |¦  «        }t          |¬¦  «        }|rdnd}|                     ¦   «         s*t          d¦  «         t          d|rdnd› d|› �¦  «         d S t	          ¦   «         rt          ¦   «          t          ¦   «          t          ¦   «         rt          ¦   «          t          ¦   «          t          |¬¦  «        s7t          d¦  «         t          d|rdnd› d	|› d
�¦  «         t          ¦   «          dt          ¦   «         dg}|r| 
                    d¦  «         t          ||dd¬¦  «         t          dt          ¦   «         g|ddd¬¦  «        }|j                             ¦   «         }|dk    r3t          dt          |¦  «                             ¦   «         › d�¦  «         nKt          dt          |¦  «                             ¦   «         › d�¦  «         t          d|rdnd› d|› �¦  «         |rt!          |¦  «        nd }|rt          d|› �¦  «         t#          ¦   «         }	|	r4t          ¦   «          t          d¦  «         |	D ]}
t          d|
› �¦  «         Œt%          |¬¦  «        }|                     dd¦  «        }|                     dd¦  «        }|                     dd¦  «        }|                     d d¦  «        }|d!k    r|d"k    rt          d#¦  «         nw|d$k    rW|t)          t*          ¦  «        k    r?t          d%¦  «         t          d&|sd'nd› d(t          ¦   «         › d)|rdnd› d|› �¦  «         n|d$k    r|rt          d*|› �¦  «         |rt          d+¦  «         nX| rt-          ¦   «          nGt/          ¦   «         \  }}|du rt          d,¦  «         n"|du rt          d-¦  «         t          d.¦  «         | rot          ¦   «          t          d/¦  «         t1          |¦  «        d0t          ¦   «         d1d2dgz   }|r| 
                    d¦  «         t3          j        |d¬3¦  «         d S d S )4Nr¶   r]  r‰   u$   âœ— Gateway service is not installedz  Run: rØ   zhermes gateway installu4   âš  Installed gateway service definition is outdatedzhermes gateway restartz  # auto-refreshes the unitr)  r8   z-lFr“   )r´   r;   r=   r·   Tr¸   r¹   rÒ   z gateway service is runningu   âœ— z gateway service is stoppedre  rf  úRecent gateway health:r°  rÄ   rÅ   rÇ   rÆ   rÕ   rÖ   uA     â�³ Restart pending: systemd is waiting to relaunch the gatewayrè   u@     âš  Planned restart is stuck in systemd failed state (exit 75)z  Run: systemctl rÙ   zreset-failed z && u     âš  Systemd unit result: uB   âœ“ System service starts at boot without requiring systemd lingerrô  rõ  rö  úRecent logs:z-uz-nÚ20rj  )rº   r»   r¼   rÜ   rŽ  rÃ  r   r§  rH  r¾   r‚   r½   rI   rJ   rÚ   rÛ   rÜ  Ú_runtime_health_linesrÏ   r’   r0   r   r÷  ru  rƒ  rG   rH   )ru  r´   rv  r‹  rh  Ú
status_cmdrX   r)  ri  Úruntime_linesrY   Ú
unit_propsrß   rà   rñ   Úresult_codery  r  Úlog_cmds                      r(   Úsystemd_statusr�  o  s4  € Ý" 6Ñ*Ô*€FÝ%¨VÐ4Ñ4Ô4€IØ &Ð.��¨B€Jà×ÒÑÔð ÝÐ4Ñ5Ô5Ð5ÝÐU 6Ð1˜˜¨rÐUÐUÈÐUÐUÑVÔVÐVØˆå$Ñ&Ô&ð Ý,Ñ.Ô.Ð.Ý‰ŒˆåÑ Ô ð Ý!Ñ#Ô#Ð#Ý‰Œˆå"¨&Ð1Ñ1Ô1ð ÝÐDÑEÔEÐEÝÐp 6Ð1˜˜¨rÐpÐpÈÐpÐpÐpÑqÔqÐqÝ‰ŒˆàÕ,Ñ.Ô.°Ð=€JØð  Ø×Ò˜$ÑÔÐåØØØØð	ñ ô ð õ Ø	Õ&Ñ(Ô(Ð)ØØØØðñ ô €Fð Œ]× Ò Ñ"Ô"€Fà�ÒÐÝÐ[Õ)¨&Ñ1Ô1×<Ò<Ñ>Ô>Ð[Ð[Ð[Ñ\Ô\Ð\Ð\åÐ[Õ)¨&Ñ1Ô1×<Ò<Ñ>Ô>Ð[Ð[Ð[Ñ\Ô\Ð\ÝÐS 6Ð1˜˜¨rÐSÐSÀzÐSÐSÑTÔTÐTàAGÐQÕ2°9Ñ=Ô=Ð=ÈT€OØð :ÝÐ8 Ð8Ð8Ñ9Ô9Ð9å)Ñ+Ô+€MØð Ý‰ŒˆÝÐ&Ñ'Ô'Ð'Ø!ð 	ð 	ˆDÝ�+�t�+�+ÑÔÐÐå.°fÐ=Ñ=Ô=€JØ—>’> -°Ñ4Ô4€LØ—’˜z¨2Ñ.Ô.€IØ!—~’~Ð&6¸Ñ;Ô;ÐØ—.’. ¨2Ñ.Ô.€KØ�|Ò#Ð#¨	°^Ò(CÐ(CÝÐQÑRÔRÐRÐRØ	˜Ò	!Ð	!Ð&6½#Õ>_Ñ:`Ô:`Ò&`Ð&`ÝÐPÑQÔQÐQÝð  d°6Ð"A ) )¸rð  dð  dÕP`ÑPbÔPbð  dð  dÐsyð  iBÐhoÐhoð  @Bð  dð  dð  Xbð  dð  dñ  	eô  	eð  	eð  	eØ	˜Ò	!Ð	! kÐ	!ÝÐ9¨KÐ9Ð9Ñ:Ô:Ð:àð 
>ÝÐRÑSÔSÐSÐSØ	ð >Ý%Ñ'Ô'Ð'Ð'å5Ñ7Ô7Ñˆ˜Ø˜TÐ!Ð!ÝÐKÑLÔLÐLÐLØ˜uÐ$Ð$ÝÐVÑWÔWÐWÝÐ<Ñ=Ô=Ð=àð ,Ý‰ŒˆÝˆnÑÔÐÝ! &Ñ)Ô)¨TÕ3CÑ3EÔ3EÀtÈTÐS_Ð,`Ñ`ˆØð 	!Ø�NŠN˜4Ñ Ô Ð ÝŒ�w¨Ð+Ñ+Ô+Ð+Ð+Ð+ð,ð ,r*   c                  ó0   — t          ¦   «         } | rd| › �ndS )z5Return the launchd service label, scoped per profile.rû  rü  )rE  rK  s    r(   rS   rS   Ò  s'   € åÑÔ€FØ,2ÐKÐ( Ð(Ð(Ð(Ð8KÐKr*   c                  ó.   — dt          j        ¦   «         › �S )Nzgui/)ri   r[  r   r*   r(   Ú_launchd_domainr„  Ø  s   € Ø•"”)‘+”+ÐÐÐr*   c                  óÌ  — t          ¦   «         } t          t          ¦  «        }t          t          ¦   «                              ¦   «         ¦  «        }t          ¦   «         dz  }|                     dd¬¦  «         t          ¦   «         }t          |¦  «        }t          ¦   «         }|rt          |dz  ¦  «        nt          t          dz  dz  ¦  «        }|rt          |¦  «        nt          t          dz  ¦  «        }t          t          dz  dz  ¦  «        }	||	g}
t          j
        d¦  «        }|rLt          t          |¦  «                             ¦   «         j        ¦  «        }||
vr|
                     |¦  «         d	                     t                               |
d
„ t"          j                             dd¦  «                             d	¦  «        D ¦   «         z   ¦  «        ¦  «        }d| › d�ddg}|r0|                     ¦   «         D ]}|                     d|› d�¦  «         Œ|                     g d¢¦  «         d                     |¦  «        }d|› d|› d|› d|› d|› d|› d|› d|› d�S )NÚlogsTra  r
  r  r   r!  r"  r&  c                 ó   — g | ]}|¯|‘ŒS r   r   ©r–   r—   s     r(   r  z*generate_launchd_plist.<locals>.<listcomp>ö  s   € Ð&]Ð&]Ð&]¨QÐ[\Ð&] qÐ&]Ð&]Ð&]r*   ÚPATHr‰   z<string>z	</string>z<string>-m</string>z <string>hermes_cli.main</string>)z<string>gateway</string>z<string>run</string>z<string>--replace</string>z	
        zÌ<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>z?</string>

    <key>ProgramArguments</key>
    <array>
        z?
    </array>
    
    <key>WorkingDirectory</key>
    <string>zf</string>
    
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>z9</string>
        <key>VIRTUAL_ENV</key>
        <string>z9</string>
        <key>HERMES_HOME</key>
        <string>zØ</string>
    </dict>
    
    <key>RunAtLoad</key>
    <true/>
    
    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>
    
    <key>StandardOutPath</key>
    <string>zH/gateway.log</string>
    
    <key>StandardErrorPath</key>
    <string>z-/gateway.error.log</string>
</dict>
</plist>
)r  r0   r  r
   rŸ   rg  rS   r    r  r-  r.  r   r'  r‚   r¥   rX  Úfromkeysri   rZ  r’   rL   r)  )r+  r,  rF  Úlog_dirr]   r6  r-  r/  r.  r0  Úpriority_dirsr1  r2  r7  Ú	prog_argsÚpartÚprog_args_xmls                    r(   Úgenerate_launchd_plistr�  Ü  sØ  € Ý!Ñ#Ô#€KÝ•lÑ#Ô#€KÝ•oÑ'Ô'×/Ò/Ñ1Ô1Ñ2Ô2€KÝÑÔ &Ñ(€GØ‡M‚M˜$¨€MÑ.Ô.Ð.ÝÑÔ€EÝ˜{Ñ+Ô+€Kõ %Ñ&Ô&€MØ-:Ðb�s�= 5Ñ(Ñ)Ô)Ð)ÅÅLÐSYÑDYÐ\aÑDaÑ@bÔ@b€HØ%2ÐR�s�=Ñ!Ô!Ð!½½LÈ6Ñ<QÑ8RÔ8R€HÝ•< .Ñ0°6Ñ9Ñ:Ô:€Hð ˜xÐ(€MÝ”L Ñ(Ô(€MØð 4Ý¥ ]Ñ 3Ô 3× ;Ò ;Ñ =Ô =Ô DÑEÔEÐØ MÐ1Ð1Ø× Ò Ð!2Ñ3Ô3Ð3Ø—’Ý�Š�mÐ&]Ð&]µ"´*·.².ÀÈÑ2LÔ2L×2RÒ2RÐSVÑ2WÔ2WÐ&]Ñ&]Ô&]Ñ]Ñ^Ô^ñô €Ið 	*�;Ð)Ð)Ð)ØØ*ð€Ið
 ð 9Ø×%Ò%Ñ'Ô'ð 	9ð 	9ˆDØ×ÒÐ7¨Ð7Ð7Ð7Ñ8Ô8Ð8Ð8Ø×Òð ð ð ñ ô ð ð
 !×%Ò% iÑ0Ô0€Mð)ð
 ð)ð )ð 
ð)ð )ð ð)ð )ð$ ð%)ð )ð( ð))ð )ð, ð-)ð )ðF ðG)ð )ðL ðM)ð )ð )ð )r*   c                  óÒ   — t          ¦   «         } |                      ¦   «         sdS |                      d¬¦  «        }t          ¦   «         }t	          |¦  «        t	          |¦  «        k    S )zICheck if the installed launchd plist matches the currently generated one.Fr”  rÛ  )rô   r¼   rš  r�  rB  )Ú
plist_pathrE  rG  s      r(   Úlaunchd_plist_is_currentr“  4  sd   € å'Ñ)Ô)€JØ×ÒÑÔð Øˆuà×$Ò$¨gÐ$Ñ6Ô6€IÝ%Ñ'Ô'€HÝ2°9Ñ=Ô=ÕAhÐiqÑArÔArÒrÐrr*   c                  ó¨  — t          ¦   «         } |                      ¦   «         rt          ¦   «         rdS |                      t	          ¦   «         d¬¦  «         t          ¦   «         }t          j        ddt          ¦   «         › d|› �gdd¬¦  «         t          j        dd	t          ¦   «         t          | ¦  «        gdd
¬¦  «         t          d¦  «         dS )u@  Rewrite the installed launchd plist when the generated definition has changed.

    Unlike systemd, launchd picks up plist changes on the next ``launchctl kill``/
    ``launchctl kickstart`` cycle â€” no daemon-reload is needed. We still bootout/
    bootstrap to make launchd re-read the updated plist immediately.
    Fr”  rÛ  rA   Úbootoutú/rî   ©rì   r=   Ú	bootstraprê   uR   â†» Updated gateway launchd service definition to match the current Hermes installT)rô   r¼   r“  rJ  r�  rS   rG   rH   r„  r0   rÜ   ©r’  r]   s     r(   Úrefresh_launchd_plist_if_neededrš  ?  s×   € õ (Ñ)Ô)€JØ×ÒÑÔð Õ":Ñ"<Ô"<ð Øˆuà×ÒÕ0Ñ2Ô2¸WÐÑEÔEÐEÝÑÔ€Eå„N�K ­Ñ/@Ô/@Ð,JÐ,JÀ5Ð,JÐ,JÐKÐSXÐbdÐeÑeÔeÐeÝ„N�K ­oÑ.?Ô.?ÅÀZÁÄÐQÐY^ÐhjÐkÑkÔkÐkÝ	Ð
^Ñ_Ô_Ð_Øˆ4r*   c                 óì  — t          ¦   «         }|                     ¦   «         rd| sbt          ¦   «         s1t          d|› �¦  «         t	          ¦   «          t          d¦  «         d S t          d|› �¦  «         t          d¦  «         d S |j                             dd¬¦  «         t          d|› �¦  «         |                     t          ¦   «         ¦  «         t          j
        dd	t          ¦   «         t          |¦  «        gdd
¬¦  «         t          ¦   «          t          d¦  «         t          ¦   «          t          d¦  «         t          d¦  «         ddlm} t          d |¦   «         › d�¦  «         d S )Nu+   â†» Repairing outdated launchd service at: u   âœ“ Service definition updatedr_  r`  Tra  zInstalling launchd service to: rA   r˜  rê   r—  u!   âœ“ Service installed and loaded!rd  z2  hermes gateway status             # Check statusr   ©Údisplay_hermes_homez
  tail -f z/logs/gateway.log  # View logs)rô   r¼   r“  rÜ   rš  r'  rg  rJ  r�  rG   rH   r„  r0   rú   r�  )r  r’  Ú_dhhs      r(   Úlaunchd_installrŸ  S  sŠ  € Ý'Ñ)Ô)€Jà×ÒÑÔð  5ð Ý'Ñ)Ô)ð 	ÝÐLÀ
ÐLÐLÑMÔMÐMÝ+Ñ-Ô-Ð-ÝÐ2Ñ3Ô3Ð3ØˆFÝÐ;¨zÐ;Ð;Ñ<Ô<Ð<ÝÐ(Ñ)Ô)Ð)ØˆàÔ×Ò D°4ÐÑ8Ô8Ð8Ý	Ð
8¨JÐ
8Ð
8Ñ9Ô9Ð9Ø×ÒÕ0Ñ2Ô2Ñ3Ô3Ð3å„N�K ­oÑ.?Ô.?ÅÀZÁÄÐQÐY]ÐgiÐjÑjÔjÐjå	�G„G€GÝ	Ð
-Ñ.Ô.Ð.Ý	�G„G€GÝ	ˆ-ÑÔÐÝ	Ð
>Ñ?Ô?Ð?Ø<Ð<Ð<Ð<Ð<Ð<Ý	Ð
=�t�t‘v”vÐ
=Ð
=Ð
=Ñ>Ô>Ð>Ð>Ð>r*   c                  ó&  — t          ¦   «         } t          ¦   «         }t          j        ddt	          ¦   «         › d|› �gdd¬¦  «         |                      ¦   «         r&|                      ¦   «          t          d| › �¦  «         t          d¦  «         d S )	NrA   r•  r–  Frî   r—  rl  u   âœ“ Service uninstalled)rô   rS   rG   rH   r„  r¼   r¹  rÜ   r™  s     r(   Úlaunchd_uninstallr¡  n  sž   € Ý'Ñ)Ô)€JÝÑÔ€EÝ„N�K ­Ñ/@Ô/@Ð,JÐ,JÀ5Ð,JÐ,JÐKÐSXÐbdÐeÑeÔeÐeà×ÒÑÔð +Ø×ÒÑÔÐÝÐ)˜ZÐ)Ð)Ñ*Ô*Ð*å	Ð
#Ñ$Ô$Ð$Ð$Ð$r*   c            	      óž  — t          ¦   «         } t          ¦   «         }|                      ¦   «         s¾t          d¦  «         | j                             dd¬¦  «         |                      t          ¦   «         d¬¦  «         t          j	        ddt          ¦   «         t          | ¦  «        gdd¬	¦  «         t          j	        dd
t          ¦   «         › d|› �gdd¬	¦  «         t          d¦  «         d S t          ¦   «          	 t          j	        dd
t          ¦   «         › d|› �gdd¬	¦  «         n”# t          j        $ r‚}|j        dvr‚ t          d¦  «         t          j	        ddt          ¦   «         t          | ¦  «        gdd¬	¦  «         t          j	        dd
t          ¦   «         › d|› �gdd¬	¦  «         Y d }~nd }~ww xY wt          d¦  «         d S )Nu:   â†» launchd plist missing; regenerating service definitionTra  r”  rÛ  rA   r˜  rê   r—  Ú	kickstartr–  u   âœ“ Service started©rC   éq   u:   â†» launchd job was unloaded; reloading service definition)rô   rS   r¼   rÜ   r'  rg  rJ  r�  rG   rH   r„  r0   rš  ÚCalledProcessErrorrT   )r’  r]   r¿  s      r(   Úlaunchd_startr§  y  s  € Ý'Ñ)Ô)€JÝÑÔ€Eð ×ÒÑÔð ÝÐJÑKÔKÐKØÔ×Ò¨°tÐÑ<Ô<Ð<Ø×ÒÕ4Ñ6Ô6ÀÐÑIÔIÐIÝŒ˜ [µ/Ñ2CÔ2CÅSÈÁ_Ä_ÐUÐ]aÐkmÐnÑnÔnÐnÝŒ˜ [µ_Ñ5FÔ5FÐ2PÐ2PÈÐ2PÐ2PÐQÐY]ÐgiÐjÑjÔjÐjÝÐ#Ñ$Ô$Ð$Øˆå#Ñ%Ô%Ð%ðkÝŒ˜ [µ_Ñ5FÔ5FÐ2PÐ2PÈÐ2PÐ2PÐQÐY]ÐgiÐjÑjÔjÐjÐjøÝÔ(ð kð kð kØŒ<˜xÐ'Ð'ØÝÐJÑKÔKÐKÝŒ˜ [µ/Ñ2CÔ2CÅSÈÁ_Ä_ÐUÐ]aÐkmÐnÑnÔnÐnÝŒ˜ [µ_Ñ5FÔ5FÐ2PÐ2PÈÐ2PÐ2PÐQÐY]ÐgiÐjÑjÔjÐjÐjÐjÐjÐjÐjøøøøðkøøøõ 
Ð
Ñ Ô Ð Ð Ð s   Ã>+D* Ä*F;Ä9A8F6Æ6F;c                  ó  — t          ¦   «         } t          ¦   «         › d| › �}	 t          j        dd|gdd¬¦  «         n'# t          j        $ r}|j        dv rn‚ Y d }~nd }~ww xY wt          dd	¬
¦  «         t          d¦  «         d S )Nr–  rA   r•  Trî   r—  r¤  ç      $@rp  ©r=   Úforce_afteru   âœ“ Service stopped)rS   r„  rG   rH   r¦  rT   Ú_wait_for_gateway_exitrÜ   )r]   Útargetr¿  s      r(   Úlaunchd_stopr®  ’  s¸   € ÝÑÔ€EÝÑ!Ô!Ð+Ð+ EÐ+Ð+€Fð
ÝŒ˜ Y°Ð7¸tÈRÐPÑPÔPÐPÐPøÝÔ(ð ð ð ØŒ<˜8Ð#Ð#Øàð ˆDˆDˆDˆDøøøøðøøøõ
  4°SÐ9Ñ9Ô9Ð9Ý	Ð
Ñ Ô Ð Ð Ð s   £> ¾A"ÁAÁA"r©  rp  r«  c                 ó4  — ddl }ddlm} |                     ¦   «         | z   }|�|                     ¦   «         |z   nd}d}|                     ¦   «         |k     r� |¦   «         }|€dS |�`|s^|                     ¦   «         |k    rF	 t	          |d¬¦  «         t          d|› d�¦  «         n# t          t          t          f$ r Y dS w xY wd}| 	                    d	¦  «         |                     ¦   «         |k     °� |¦   «         }|�t          d|› d
| › d�¦  «         dS dS )u‚  Wait for the gateway process (by saved PID) to exit.

    Uses the PID from the gateway.pid file â€” not launchd labels â€” so this
    works correctly when multiple gateway instances run under separate
    HERMES_HOME directories.

    Args:
        timeout: Total seconds to wait before giving up.
        force_after: Seconds of graceful waiting before escalating to force-kill.
    r   Nr­   FTr  u   âš  Gateway PID z& did not exit gracefully; sent SIGKILLg333333Ó?z still running after u   s â€” restart may fail)
ry   r°   r®   rz   r   rÜ   rr   rs   rt   r|   )	r=   r«  ry   r®   r~   Úforce_deadlineÚ
force_sentr\   Úremaining_pids	            r(   r¬  r¬  £  sl  € ð €K€K€KØ.Ð.Ð.Ð.Ð.Ð.à�~Š~ÑÔ 'Ñ)€HØ9DÐ9P�d—n’nÑ&Ô&¨Ñ4Ð4ÐVZ€NØ€Jà
�.Š.Ñ
Ô
˜XÒ
%Ð
%ØˆoÑÔˆØˆ;Ø�4àÐ"¨:Ð"¸$¿.º.Ñ:JÔ:JÈnÒ:\Ð:\ðÝ˜c¨Ð.Ñ.Ô.Ð.ÝÐT¨ÐTÐTÐTÑUÔUÐUÐUøÝ&­½ÐAð ð ð Ø�t�tðøøøàˆJà�
Š
�3‰Œˆð �.Š.Ñ
Ô
˜XÒ
%Ð
%ð" $�OÑ%Ô%€MØÐ ÝÐd ÐdÐdÀWÐdÐdÐdÑeÔeÐeØˆuØˆ4s   Â$B' Â'CÃCc            	      ó  — t          ¦   «         } t          ¦   «         › d| › �}t          ¦   «         }ddlm} 	  |¦   «         }|� t          |¦  «        rt          d¦  «         d S |�[	 t          |d¬¦  «         n# t          t          t          f$ r d }Y nw xY w|�'t          |d ¬¦  «        }|st          d|d	›d
�¦  «         t          j        ddd|gdd¬¦  «         t          d¦  «         d S # t          j        $ r�}|j        dvr‚ t          d¦  «         t!          ¦   «         }t          j        ddt          ¦   «         t#          |¦  «        gdd¬¦  «         t          j        dd|gdd¬¦  «         t          d¦  «         Y d }~d S d }~ww xY w)Nr–  r   r­   u   âœ“ Service restart requestedFr  rª  u"   âš  Gateway drain timed out after z.0fu   s â€” forcing launchd restartrA   r£  z-kTrî   r—  u   âœ“ Service restartedr¤  u'   â†» launchd job was unloaded; reloadingr˜  rê   )rS   r„  r(  r°   r®   ru   rÜ   r   rr   rs   rt   r¬  rG   rH   r¦  rT   rô   r0   )r]   r­  rv   r®   r\   Úexitedr¿  r’  s           r(   Úlaunchd_restartrµ  Í  só  € ÝÑÔ€EÝÑ!Ô!Ð+Ð+ EÐ+Ð+€FÝ.Ñ0Ô0€MØ.Ð.Ð.Ð.Ð.Ð.ð'ØˆoÑÔˆØˆ?Õ<¸SÑAÔAˆ?ÝÐ1Ñ2Ô2Ð2ØˆFØˆ?ðÝ˜c¨Ð/Ñ/Ô/Ð/Ð/øÝ&­½ÐAð ð ð Ø���ðøøøàˆÝ/¸ÐSWÐXÑXÔX�Øð qÝÐo¸}ÐoÐoÐoÐoÑpÔpÐpÝŒ˜ [°$¸Ð?ÀtÐUWÐXÑXÔXÐXÝÐ%Ñ&Ô&Ð&Ð&Ð&øÝÔ(ð 'ð 'ð 'ØŒ<˜xÐ'Ð'ØåÐ7Ñ8Ô8Ð8Ý+Ñ-Ô-ˆ
ÝŒ˜ [µ/Ñ2CÔ2CÅSÈÁ_Ä_ÐUÐ]aÐkmÐnÑnÔnÐnÝŒ˜ [°&Ð9ÀÈrÐRÑRÔRÐRÝÐ%Ñ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&øøøøð'øøøsC   ·*C, Á#C, Á&A8 Á7C, Á8BÂC, ÂBÂAC, Ã,F
Ã;BFÆF
c                 óè  — t          ¦   «         }t          ¦   «         }	 t          j        dd|gddd¬¦  «        }|j        dk    }|j        }n# t          j        $ r d}d}Y nw xY wt          d	|› �¦  «         t          ¦   «         rt          d
¦  «         nt          d¦  «         t          d¦  «         |rt          d¦  «         t          |¦  «         n-t          d¦  «         t          d¦  «         t          d¦  «         | rmt          ¦   «         dz  dz  }| 
                    ¦   «         rGt          ¦   «          t          d¦  «         t          j        ddt          |¦  «        gd¬¦  «         d S d S d S )NrA   rB   Tr“   r:   r   Fr‰   zLaunchd plist: u9   âœ“ Service definition matches the current Hermes installuF   âš  Service definition is stale relative to the current Hermes installz  Run: hermes gateway startu   âœ“ Gateway service is loadedu!   âœ— Gateway service is not loadedzB  Service definition exists locally but launchd has not loaded it.r†  zgateway.logry  Útailz-20rj  )rô   rS   rG   rH   rT   rI   rP   rÜ   r“  r
   r¼   r0   )ru  r’  r]   rX   ÚloadedÚloaded_outputÚlog_files          r(   Úlaunchd_statusr»  í  s¾  € Ý'Ñ)Ô)€JÝÑÔ€EðÝ”Ø˜& %Ð(ØØØð	
ñ 
ô 
ˆð Ô" aÒ'ˆØœˆˆøÝÔ$ð ð ð ØˆØˆˆˆðøøøõ 
Ð
(˜JÐ
(Ð
(Ñ)Ô)Ð)ÝÑ!Ô!ð -ÝÐIÑJÔJÐJÐJåÐVÑWÔWÐWÝÐ+Ñ,Ô,Ð,àð -ÝÐ-Ñ.Ô.Ð.ÝˆmÑÔÐÐåÐ1Ñ2Ô2Ð2ÝÐRÑSÔSÐSÝÐ+Ñ,Ô,Ð,àð GÝ"Ñ$Ô$ vÑ-°Ñ=ˆØ�?Š?ÑÔð 	GÝ‰GŒGˆGÝ�.Ñ!Ô!Ð!ÝŒN˜F E­3¨x©=¬=Ð9À2ÐFÑFÔFÐFÐFÐFðGð Gð	Gð 	Gs   ž-A ÁA"Á!A"ÚverboseÚquietÚreplacec                 óÀ  — t           j                             dt          t          ¦  «        ¦  «         ddlm} t          d¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          |rd	n| }t          j	         |||¬
¦  «        ¦  «        }|st          j
        d¦  «         d	S d	S )aŽ  Run the gateway in foreground.
    
    Args:
        verbose: Stderr log verbosity count added on top of default WARNING (0=WARNING, 1=INFO, 2+=DEBUG).
        quiet: Suppress all stderr log output.
        replace: If True, kill any existing gateway instance before starting.
                 This prevents systemd restart loops when the old process
                 hasn't fully exited yet.
    r   )Ústart_gatewayõ±   â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”�u@   â”‚           âš• Hermes Gateway Starting...                 â”‚õ±   â”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤u@   â”‚  Messaging platforms + cron scheduler                    â”‚u?   â”‚  Press Ctrl+C to stop                                   â”‚õ±   â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜N)r¾  Ú	verbosityr`   )r  r¥  Úinsertr0   r  Úgateway.runrÀ  rÜ   ÚasynciorH   rÆ  )r¼  r½  r¾  rÀ  rÄ  Úsuccesss         r(   Úrun_gatewayrÉ  	  s  € õ „H‡O‚O�A•s�<Ñ(Ô(Ñ)Ô)Ð)à)Ð)Ð)Ð)Ð)Ð)å	ð  ~ñ  ô  ð  Ý	Ð
LÑMÔMÐMÝ	ð  ~ñ  ô  ð  Ý	Ð
LÑMÔMÐMÝ	Ð
KÑLÔLÐLÝ	ð  ~ñ  ô  ð  Ý	�G„G€Gð Ð*�� 7€IÝŒk˜-˜-°À9ÐMÑMÔMÑNÔN€GØð ÝŒ�‰Œˆˆˆðð r*   ÚtelegramÚTelegramu   ðŸ“±ÚTELEGRAM_BOT_TOKEN)z'1. Open Telegram and message @BotFatherz92. Send /newbot and follow the prompts to create your botz)3. Copy the bot token BotFather gives youuQ   4. To find your user ID: message @userinfobot â€” it replies with your numeric IDz	Bot tokenz/Paste the token from @BotFather (step 3 above).)rR  r   ÚpasswordÚhelpÚTELEGRAM_ALLOWED_USERSz"Allowed user IDs (comma-separated)z%Paste your user ID from step 4 above.)rR  r   rÍ  Úis_allowlistrÎ  ÚTELEGRAM_HOME_CHANNELzVHome channel ID (for cron/notification delivery, or empty to set later with /set-home)zPFor DMs, this is your user ID. You can set it later by typing /set-home in chat.)rÍ   r]   ÚemojiÚ	token_varÚsetup_instructionsÚvarsÚdiscordÚDiscordu   ðŸ’¬ÚDISCORD_BOT_TOKEN)uH   1. Go to https://discord.com/developers/applications â†’ New Applicationu3   2. Go to Bot â†’ Reset Token â†’ copy the bot tokenuH   3. Enable: Bot â†’ Privileged Gateway Intents â†’ Message Content Intentz!4. Invite the bot to your server:u2      OAuth2 â†’ URL Generator â†’ check BOTH scopes:z
     - botz<     - applications.commands  (required for slash commands!)zE   Bot Permissions: Send Messages, Read Message History, Attach Filesz6   Copy the URL and open it in your browser to invite.z?5. Get your user ID: enable Developer Mode in Discord settings,u)      then right-click your name â†’ Copy IDz"Paste the token from step 2 above.ÚDISCORD_ALLOWED_USERSz/Allowed user IDs or usernames (comma-separated)z%Paste your user ID from step 5 above.ÚDISCORD_HOME_CHANNELuD   Right-click a channel â†’ Copy Channel ID (requires Developer Mode).ÚslackÚSlacku   ðŸ’¼ÚSLACK_BOT_TOKEN)uG   1. Go to https://api.slack.com/apps â†’ Create New App â†’ From Scratchu:   2. Enable Socket Mode: Settings â†’ Socket Mode â†’ EnableuR      Create an App-Level Token with scope: connections:write â†’ copy xapp-... tokenuD   3. Add Bot Token Scopes: Features â†’ OAuth & Permissions â†’ ScopeszL   Required: chat:write, app_mentions:read, channels:history, channels:read,zU   groups:history, im:history, im:read, im:write, users:read, files:read, files:writeuC   4. Subscribe to Events: Features â†’ Event Subscriptions â†’ Enablez=   Required events: message.im, message.channels, app_mentionz2   Optional: message.groups (for private channels)u>      âš  Without message.channels the bot will ONLY work in DMs!uI   5. Install to Workspace: Settings â†’ Install App â†’ copy xoxb-... tokenz56. Reinstall the app after any scope or event changesuJ   7. Find your user ID: click your profile â†’ three dots â†’ Copy member IDz/8. Invite the bot to channels: /invite @YourBotzBot Token (xoxb-...)z&Paste the bot token from step 3 above.ÚSLACK_APP_TOKENzApp Token (xapp-...)z,Paste the app-level token from step 4 above.ÚSLACK_ALLOWED_USERSz'Paste your member ID from step 7 above.ÚmatrixÚMatrixu   ðŸ”�ÚMATRIX_ACCESS_TOKEN)zX1. Works with any Matrix homeserver (self-hosted Synapse/Conduit/Dendrite or matrix.org)z@2. Create a bot user on your homeserver, or use your own accountuN   3. Get an access token: Element â†’ Settings â†’ Help & About â†’ Access TokenzI   Or via API: curl -X POST https://your-server/_matrix/client/v3/login \zK     -d '{"type":"m.login.password","user":"@bot:server","password":"..."}'zL4. Alternatively, provide user ID + password and Hermes will log in directlyzT5. For E2EE: set MATRIX_ENCRYPTION=true (requires pip install 'mautrix[encryption]')zN6. To find your user ID: it's @username:your-server (shown in Element profile)ÚMATRIX_HOMESERVERz0Homeserver URL (e.g. https://matrix.example.org)z@Your Matrix homeserver URL. Works with any self-hosted instance.z8Access token (leave empty to use password login instead)zMPaste your access token, or leave empty and provide user ID + password below.ÚMATRIX_USER_IDu5   User ID (@bot:server â€” required for password login)z4Full Matrix user ID, e.g. @hermes:matrix.example.orgÚMATRIX_ALLOWED_USERSz4Allowed user IDs (comma-separated, e.g. @you:server)z.Matrix user IDs who can interact with the bot.ÚMATRIX_HOME_ROOMzSHome room ID (for cron/notification delivery, or empty to set later with /set-home)zLRoom ID (e.g. !abc123:server) for delivering cron results and notifications.Ú
mattermostÚ
MattermostÚMATTERMOST_TOKEN)uC   1. In Mattermost: Integrations â†’ Bot Accounts â†’ Add Bot AccountuE      (System Console â†’ Integrations â†’ Bot Accounts must be enabled)z:2. Give it a username (e.g. hermes) and copy the bot tokenuK   3. Works with any self-hosted Mattermost instance â€” enter your server URLuA   4. To find your user ID: click your avatar (top-left) â†’ Profileu8      Your user ID is displayed there â€” click it to copy.uI      âš  This is NOT your username â€” it's a 26-character alphanumeric ID.uL   5. To get a channel ID: click the channel name â†’ View Info â†’ copy the IDÚMATTERMOST_URLz(Server URL (e.g. https://mm.example.com)z@Your Mattermost server URL. Works with any self-hosted instance.z&Paste the bot token from step 2 above.ÚMATTERMOST_ALLOWED_USERSz*Your Mattermost user ID from step 4 above.ÚMATTERMOST_HOME_CHANNELz@Channel ID where Hermes delivers cron results and notifications.ÚMATTERMOST_REPLY_MODEuT   Reply mode â€” 'off' for flat messages, 'thread' for threaded replies (default: off)zFoff = flat channel messages, thread = replies nest under your message.ÚwhatsappÚWhatsAppu   ðŸ“²ÚWHATSAPP_ENABLED)rÍ   r]   rÒ  rÓ  rp   ÚSignalu   ðŸ“¡ÚSIGNAL_HTTP_URLÚemailÚEmailu   ðŸ“§ÚEMAIL_ADDRESS)z61. Use a dedicated email account for your Hermes agentz82. For Gmail: enable 2FA, then create an App Password atz,   https://myaccount.google.com/apppasswordszH3. For other providers: use your email password or app-specific passwordz-4. IMAP must be enabled on your email accountzEmail addressz;The email address Hermes will use (e.g., hermes@gmail.com).ÚEMAIL_PASSWORDz Email password (or app password)z;For Gmail, use an App Password (not your regular password).ÚEMAIL_IMAP_HOSTz	IMAP hostzBe.g., imap.gmail.com for Gmail, outlook.office365.com for Outlook.ÚEMAIL_SMTP_HOSTz	SMTP hostz?e.g., smtp.gmail.com for Gmail, smtp.office365.com for Outlook.ÚEMAIL_ALLOWED_USERSz'Allowed sender emails (comma-separated)z3Only emails from these addresses will be processed.ÚsmszSMS (Twilio)ÚTWILIO_ACCOUNT_SID)z51. Create a Twilio account at https://www.twilio.com/zH2. Get your Account SID and Auth Token from the Twilio Console dashboardz93. Buy or configure a phone number capable of sending SMSz+4. Set up your webhook URL for inbound SMS:uF      Twilio Console â†’ Phone Numbers â†’ Active Numbers â†’ your numberu`      â†’ Messaging â†’ A MESSAGE COMES IN â†’ Webhook â†’ https://your-server:8080/webhooks/twiliozTwilio Account SIDz&Found on the Twilio Console dashboard.ÚTWILIO_AUTH_TOKENzTwilio Auth Tokenz8Found on the Twilio Console dashboard (click to reveal).ÚTWILIO_PHONE_NUMBERz5Twilio phone number (E.164 format, e.g. +15551234567)z)The Twilio phone number to send SMS from.ÚSMS_ALLOWED_USERSz5Allowed phone numbers (comma-separated, E.164 format)z9Only messages from these phone numbers will be processed.ÚSMS_HOME_CHANNELzDHome channel phone number (for cron/notification delivery, or empty)z>Phone number to deliver cron job results and notifications to.ÚdingtalkÚDingTalkÚDINGTALK_CLIENT_ID)u=   1. Go to https://open-dev.dingtalk.com â†’ Create ApplicationzQ2. Under 'Credentials', copy the AppKey (Client ID) and AppSecret (Client Secret)z.3. Enable 'Stream Mode' under the bot settingsz54. Add the bot to a group chat or message it directlyzAppKey (Client ID)z6The AppKey from your DingTalk application credentials.ÚDINGTALK_CLIENT_SECRETzAppSecret (Client Secret)z9The AppSecret from your DingTalk application credentials.ÚfeishuzFeishu / Larku   ðŸª½ÚFEISHU_APP_ID)zJ1. Go to https://open.feishu.cn/ (or https://open.larksuite.com/ for Lark)z32. Create an app and copy the App ID and App Secretz(3. Enable the Bot capability for the appz<4. Choose WebSocket (recommended) or Webhook connection modez55. Add the bot to a group chat or message it directlyz?6. Restrict access with FEISHU_ALLOWED_USERS for production usezApp IDz-The App ID from your Feishu/Lark application.ÚFEISHU_APP_SECRETz
App Secretz1The App Secret from your Feishu/Lark application.ÚFEISHU_DOMAINu+   Domain â€” feishu or lark (default: feishu)z@Use 'feishu' for Feishu China, or 'lark' for Lark international.ÚFEISHU_CONNECTION_MODEu=   Connection mode â€” websocket or webhook (default: websocket)zCwebsocket is recommended unless you specifically need webhook mode.ÚFEISHU_ALLOWED_USERSz,Allowed user IDs (comma-separated, or empty)z;Restrict which Feishu/Lark users can interact with the bot.ÚFEISHU_HOME_CHANNELz/Home chat ID (optional, for cron/notifications)z0Chat ID for scheduled results and notifications.ÚwecomzWeCom (Enterprise WeChat)ÚWECOM_BOT_ID)u?   1. Go to WeCom Admin Console â†’ Applications â†’ Create AI Botz=2. Copy the Bot ID and Secret from the bot's credentials pageu?   3. The bot connects via WebSocket â€” no public endpoint neededz>4. Add the bot to a group chat or message it directly in WeComz>5. Restrict access with WECOM_ALLOWED_USERS for production usezBot IDz"The Bot ID from your WeCom AI Bot.ÚWECOM_SECRETÚSecretz"The secret from your WeCom AI Bot.ÚWECOM_ALLOWED_USERSz5Restrict which WeCom users can interact with the bot.ÚWECOM_HOME_CHANNELÚwecom_callbackzWeCom Callback (Self-Built App)ÚWECOM_CALLBACK_CORP_ID)uG   1. Go to WeCom Admin Console â†’ Applications â†’ Create Self-Built AppzC2. Note the Corp ID (top of admin console) and create a Corp SecretzM3. Under Receive Messages, configure the callback URL to point to your serverzD4. Copy the Token and EncodingAESKey from the callback configurationuN   5. The adapter runs an HTTP server â€” ensure the port is reachable from WeComzG6. Restrict access with WECOM_CALLBACK_ALLOWED_USERS for production usezCorp IDzYour WeCom enterprise Corp ID.ÚWECOM_CALLBACK_CORP_SECRETzCorp Secretz+The secret for your self-built application.ÚWECOM_CALLBACK_AGENT_IDzAgent IDz,The Agent ID of your self-built application.ÚWECOM_CALLBACK_TOKENzCallback Tokenz1The Token from your WeCom callback configuration.ÚWECOM_CALLBACK_ENCODING_AES_KEYzEncoding AES Keyz:The EncodingAESKey from your WeCom callback configuration.ÚWECOM_CALLBACK_PORTz$Callback server port (default: 8645)z"Port for the HTTP callback server.ÚWECOM_CALLBACK_ALLOWED_USERSz5Restrict which WeCom users can interact with the app.ÚweixinzWeixin / WeChatÚWEIXIN_ACCOUNT_IDÚbluebubbleszBlueBubbles (iMessage)ÚBLUEBUBBLES_SERVER_URL)	zF1. Install BlueBubbles on a Mac that will act as your iMessage server:z   https://bluebubbles.app/uG   2. Complete the BlueBubbles setup wizard â€” sign in with your Apple IDuD   3. In BlueBubbles Settings â†’ API, note the Server URL and passwordz84. The server URL is typically http://<your-mac-ip>:1234z<5. Hermes connects via the BlueBubbles REST API and receivesz(   incoming messages via a local webhookzJ6. To authorize users, use DM pairing: hermes pairing generate bluebubblesuD      Share the code â€” the user sends it via iMessage to get approvedz6BlueBubbles server URL (e.g. http://192.168.1.10:1234)u.   The URL shown in BlueBubbles Settings â†’ API.ÚBLUEBUBBLES_PASSWORDzBlueBubbles server passwordu3   The password shown in BlueBubbles Settings â†’ API.ÚBLUEBUBBLES_ALLOWED_USERSz]Pre-authorized phone numbers or iMessage IDs (comma-separated, or leave empty for DM pairing)u_   Optional â€” pre-authorize specific users. Leave empty to use DM pairing instead (recommended).ÚBLUEBUBBLES_HOME_CHANNELzKHome channel (phone number or iMessage ID for cron/notifications, or empty)zFPhone number or Apple ID to deliver cron results and notifications to.ÚqqbotzQQ Botu   ðŸ�§Ú	QQ_APP_ID)z,1. Register a QQ Bot application at q.qq.comz<2. Note your App ID and App Secret from the application pagez;3. Enable the required intents (C2C, Group, Guild messages)z'4. Configure sandbox or publish the botzQQ Bot App IDz!Your QQ Bot App ID from q.qq.com.ÚQQ_CLIENT_SECRETzQQ Bot App Secretz%Your QQ Bot App Secret from q.qq.com.ÚQQ_ALLOWED_USERSzCAllowed user OpenIDs (comma-separated, leave empty for open access)u9   Optional â€” restrict DM access to specific user OpenIDs.ÚQQBOT_HOME_CHANNELz<Home channel (user/group OpenID for cron delivery, or empty)z4OpenID to deliver cron results and notifications to.r  c                 óˆ  — | d         }t          |¦  «        }|dk    rK|rG|                     ¦   «         dk    r/t          ¦   «         dz  dz  dz  }|                     ¦   «         rdS dS d	S |                      d
¦  «        dk    rt          d¦  «        }|r|rdS |s|rdS d	S |                      d
¦  «        dk    rYt          d¦  «        }t          d¦  «        }t          d¦  «        }t          ||||g¦  «        rdS t          ||||g¦  «        rdS d	S |                      d
¦  «        dk    r^t          d¦  «        }t          d¦  «        }	|s|	r2|r0t          d¦  «        }
|
r|
                     ¦   «         dv rdnd}d|› �S |s|	s|rdS d	S |                      d
¦  «        dk    rt          d¦  «        }|r|rdS |s|rdS d	S |rdS d	S )z³Return a plain-text status string for a platform.

    Returns uncolored text so it can safely be embedded in
    simple_term_menu items (ANSI codes break width calculation).
    rÓ  rð  rí  rî  Úsessionz
creds.jsonzconfigured + pairedzenabled, not pairedznot configuredrÍ   rp   ÚSIGNAL_ACCOUNTÚ
configuredzpartially configuredró  rö  r÷  rø  rà  rã  ÚMATRIX_PASSWORDÚMATRIX_ENCRYPTION)rí  rë  rì  z + E2EEr‰   r  ÚWEIXIN_TOKEN)r	   rï   r
   r¼   r’   Úallr£   )r  rÓ  ÚvalÚsession_fileÚaccountrÏ  ÚimapÚsmtpÚ
homeserverrÍ  Úe2eerL  Útokens                r(   Ú_platform_statusr5  ª
  sh  € ð ˜Ô%€IÝ
˜	Ñ
"Ô
"€CØÐ&Ò&Ð&Øð 	)�3—9’9‘;”; &Ò(Ð(Ý*Ñ,Ô,¨zÑ9¸IÑEÈÑTˆLØ×"Ò"Ñ$Ô$ð -Ø,Ð,Ø(Ð(ØÐØ‡|‚|�EÑÔ˜hÒ&Ð&ÝÐ 0Ñ1Ô1ˆØð 	 �7ð 	 Ø�<Øð 	*�'ð 	*Ø)Ð)ØÐØ‡|‚|�EÑÔ˜gÒ%Ð%ÝÐ,Ñ-Ô-ˆÝÐ.Ñ/Ô/ˆÝÐ.Ñ/Ô/ˆÝ��S˜$ Ð%Ñ&Ô&ð 	 Ø�<Ý��S˜$ Ð%Ñ&Ô&ð 	*Ø)Ð)ØÐØ‡|‚|�EÑÔ˜hÒ&Ð&Ý"Ð#6Ñ7Ô7ˆ
Ý Ð!2Ñ3Ô3ˆØð 	)�8ð 	) ð 	)Ý Ð!4Ñ5Ô5ˆDØ"&ÐW¨4¯:ª:©<¬<Ð;OÐ+OÐ+O�Y�YÐUWˆFØ( Ð(Ð(Ð(Øð 	*�(ð 	*˜jð 	*Ø)Ð)ØÐØ‡|‚|�EÑÔ˜hÒ&Ð&Ý˜nÑ-Ô-ˆØð 	 �5ð 	 Ø�<Øð 	*�%ð 	*Ø)Ð)ØÐØ
ð Øˆ|ØÐr*   c                  óò  — 	 ddl m}  n# t          $ r g cY S w xY w | ¦   «         }|sg S g }|                     d¦  «        }|                     d¦  «        }|                     d¦  «        }|                     d¦  «        }|                     di ¦  «        pi }|                     ¦   «         D ]P\  }}	|	                     d¦  «        d	k    r2|	                     d
¦  «        pd}
|                     d|› d|
› �¦  «         ŒQ|dk    r|r|                     d|› �¦  «         nZ|dk    r4|rdnd}t          |pd¦  «        }|                     d|› d|› d�¦  «         n |dk    r|r|                     d|› �¦  «         |S )z<Summarize the latest persisted gateway runtime health state.r   rä   Úgateway_stateÚexit_reasonÚactive_agentsræ   Ú	platformsÚstateÚfatalÚerror_messagezunknown errorr×   r  Ústartup_failedu   âš  Last startup issue: Údrainingrs  Úshutdownu   â�³ Gateway draining for z (z active agent(s))Ústoppedu   âš  Last shutdown reason: )r°   rå   r±   r’   Úitemsr‚   r3   )rå   r;  Úlinesr7  r8  r9  ræ   r:  r  ÚpdataÚmessagerÄ  Úcounts                r(   r{  r{  ß
  sá  € ðØ6Ð6Ð6Ð6Ð6Ð6Ð6øÝð ð ð Øˆ	ˆ	ˆ	ðøøøð  ÐÑ!Ô!€EØð Øˆ	à€EØ—I’I˜oÑ.Ô.€MØ—)’)˜MÑ*Ô*€KØ—I’I˜oÑ.Ô.€MØŸ	š	Ð"5Ñ6Ô6ÐØ—	’	˜+ rÑ*Ô*Ð0¨b€Ià$Ÿ?š?Ñ,Ô,ð 7ð 7‰ˆ�%Ø�9Š9�WÑÔ Ò(Ð(Ø—i’i Ñ0Ô0ÐC°OˆGØ�LŠLÐ5 Ð5Ð5¨GÐ5Ð5Ñ6Ô6Ð6øàÐ(Ò(Ð(¨[Ð(Ø�ŠÐ=°Ð=Ð=Ñ>Ô>Ð>Ð>Ø	˜*Ò	$Ð	$Ø/Ð?��°ZˆÝ�MÐ& QÑ'Ô'ˆØ�ŠÐS°ÐSÐS¸5ÐSÐSÐSÑTÔTÐTÐTØ	˜)Ò	#Ð	#¨Ð	#Ø�ŠÐ?°+Ð?Ð?Ñ@Ô@Ð@à€Ls   ‚	 ‰—c           	      ó"	  — | d         }| d         }| d         }t          ¦   «          t          t          d|› d|› d�t          j        ¦  «        ¦  «         |                      d¦  «        }|r%t          ¦   «          |D ]}t          d|› �¦  «         Œt          |¦  «        }|r6t          ¦   «          t          |› d	�¦  «         t          d
|› d�d¦  «        sdS d}| d         D �]ó}t          ¦   «          t          d|d         › �¦  «         t          |d         ¦  «        }	|	r|d         |k    rt          d|	› �¦  «         |                     d¦  «        �rît          d¦  «         t          d¦  «         t          d¦  «         t          d|d         › �d¬¦  «        }
|
�r%|
 
                    dd¦  «        }d|d         v rÝg }|                     d¦  «        D ]°}|                     ¦   «         }|                     d¦  «        r=|                     d¦  «        r(|                     d¦  «                             d¦  «        }|                     ¦   «                              d¦  «        r
|dd…         }|r|                     |¦  «         Œ±d                     |¦  «        }t)          |d         |¦  «         t          d ¦  «         |}n}t          ¦   «          g d!¢}t+          d"|d#¦  «        }|d$k    r t)          d%d&¦  «         t-          d'¦  «         n4|d#k    rt          d(¦  «         t          d)¦  «         nt          d*¦  «         �Œbt          d|d         › �|                     d+d¦  «        ¬¦  «        }
|
r0t)          |d         |
¦  «         t          d,|d         › �¦  «         �ŒÂ|d         |k    rt-          d-|› d.�¦  «          dS t          d/¦  «         �Œõ|                     ¦   «         › d0�}t          |¦  «        }|rm|sk|d1k    re|                     d¦  «        d$                              ¦   «         }|r6t          d2|› d3�d4¦  «        r"t)          ||¦  «         t          d5|› �¦  «         t          ¦   «          t          |› d|› d6�¦  «         dS )7z2Interactive setup for Telegram, Discord, or Slack.rÒ  r]   rÓ  õ     â”€â”€â”€ rœ   õ    Setup â”€â”€â”€rÔ  r°  z is already configured.ú  Reconfigure ú?FNrÕ  rÎ  rR  z  Current: rÐ  ú7  The gateway DENIES all users by default for security.z7  Enter user IDs to create an allowlist, or leave emptyz-  and you'll be asked about open access next.r   ©rÍ  r‰   ÚDISCORDrÊ   z<@ú>z<@!zuser:r9   õ7     Saved â€” only these users can interact with the bot.)ú/Enable open access (anyone can message the bot)úXUse DM pairing (unknown users request access, you approve with 'hermes pairing approve')ú7Skip for now (bot will deny all users until configured)ú+  How should unauthorized users be handled?r`   r   ÚGATEWAY_ALLOW_ALL_USERSrí  õ2     Open access enabled â€” anyone can use your bot!õB     DM pairing mode â€” users will receive a code to request access.ú8  Approve with: hermes pairing approve <platform> <code>õ9     Skipped â€” configure later with 'hermes gateway setup'rÍ  z  Saved u     Skipped â€” z won't work without this.z  Skipped (can configure later)Ú_HOME_CHANNELrË  z  Use your user ID (ú) as the home channel?Tú  Home channel set to z configured!)rÜ   r   r   ÚCYANr’   r   r	   r   r   r   r¾  rL   rJ   r¢   rM   Úlstripr;  rï   r‚   r¥   r   r   r   Úupper)r  rÒ  r]   rÓ  ÚinstructionsrY   Úexisting_tokenÚallowed_val_setÚvarÚexistingrÎ   ÚcleanedrZ   r`  Úaccess_choicesÚ
access_idxÚhome_varÚhome_valÚfirst_ids                      r(   Ú_setup_standard_platformrk    s  € à�WÔ€EØ�WÔ€EØ˜Ô%€Iå	�G„G€GÝ	�%Ð>˜uÐ>Ð> uÐ>Ð>Ð>ÅÄÑ
LÔ
LÑMÔMÐMð —<’<Ð 4Ñ5Ô5€LØð $Ý‰ŒˆØ ð 	$ð 	$ˆDÝ�{˜D�{�{Ñ#Ô#Ð#Ð#å" 9Ñ-Ô-€NØð Ý‰ŒˆÝ˜Ð7Ð7Ð7Ñ8Ô8Ð8ÝÐ6¨eÐ6Ð6Ð6¸Ñ>Ô>ð 	ØˆFà€Oà˜Ôð 9:ñ 9:ˆÝ‰ŒˆÝÐ%˜˜FœÐ%Ð%Ñ&Ô&Ð&Ý   V¤Ñ-Ô-ˆØð 	1˜˜Fœ yÒ0Ð0ÝÐ/ XÐ/Ð/Ñ0Ô0Ð0ð �7Š7�>Ñ"Ô"ñ '	ÝÐPÑQÔQÐQÝÐPÑQÔQÐQÝÐFÑGÔGÐGÝÐ/  H¤Ð/Ð/¸%Ð@Ñ@Ô@ˆEØñ !\ØŸ-š-¨¨RÑ0Ô0�à  F¤Ð+Ð+Ø�EØ&Ÿ}š}¨SÑ1Ô1ð .ð .˜Ø!Ÿiši™kœk˜ØŸ>š>¨$Ñ/Ô/ð @°C·L²LÀÑ4EÔ4Eð @Ø"%§*¢*¨UÑ"3Ô"3×":Ò":¸3Ñ"?Ô"?˜CØŸ9š9™;œ;×1Ò1°'Ñ:Ô:ð *Ø"% a b b¤'˜CØð .Ø!ŸLšL¨Ñ-Ô-Ð-øØ!Ÿhšh u™oœo�GÝ˜s 6œ{¨GÑ4Ô4Ð4ÝÐWÑXÔXÐXØ")��õ ‘”�ð"ð "ð "�õ
 +Ð+XÐZhÐjkÑlÔl�
Ø ’?�?Ý"Ð#<¸fÑEÔEÐEÝ!Ð"VÑWÔWÐWÐWØ 1’_�_Ý!Ð"fÑgÔgÐgÝÐYÑZÔZÐZÐZåÐZÑ[Ô[Ð[ÙåÐ+˜C œMÐ+Ð+°c·g²g¸jÈ%Ñ6PÔ6PÐQÑQÔQˆØð 	:Ý˜3˜vœ;¨Ñ.Ô.Ð.ÝÐ2 S¨¤[Ð2Ð2Ñ3Ô3Ð3Ñ3Ø�Œ[˜IÒ%Ð%ÝÐK¨5ÐKÐKÐKÑLÔLÐLØˆFˆFåÐ8Ñ9Ô9Ð9Ñ9ð —+’+‘-”-Ð.Ð.Ð.€HÝ˜XÑ&Ô&€HØð ?˜xð ?¨E°ZÒ,?Ð,?Ø"×(Ò(¨Ñ-Ô-¨aÔ0×6Ò6Ñ8Ô8ˆØð 	?�Ð&]¸XÐ&]Ð&]Ð&]Ð_cÑdÔdð 	?Ý˜8 XÑ.Ô.Ð.ÝÐ=°8Ð=Ð=Ñ>Ô>Ð>å	�G„G€GÝ�UÐ0Ð0˜UÐ0Ð0Ð0Ñ1Ô1Ð1Ð1Ð1r*   c                  óT   — ddl m}  ddl} | |                     ¦   «         ¦  «         dS )z-Delegate to the existing WhatsApp setup flow.r   )Úcmd_whatsappN)Úhermes_cli.mainrm  ÚargparseÚ	Namespace)rm  ro  s     r(   Ú_setup_whatsapprq  d  s?   € à,Ð,Ð,Ð,Ð,Ð,Ø€O€O€OØ€L�×#Ò#Ñ%Ô%Ñ&Ô&Ð&Ð&Ð&r*   c                  ó`   — t          d„ t          D ¦   «         ¦  «        } t          | ¦  «         dS )z0Configure Email via the standard platform setup.c              3   ó2   K  — | ]}|d          dk    ¯|V — ŒdS )rÍ   ró  Nr   rˆ  s     r(   r™   z_setup_email.<locals>.<genexpr>m  s0   è è € ÐGÐG °1°U´8¸wÒ3FÐ3F˜!Ð3FÐ3FÐ3FÐ3FÐGÐGr*   N©ÚnextÚ
_PLATFORMSrk  )Úemail_platforms    r(   Ú_setup_emailrx  k  s2   € åÐGÐG¥ZÐGÑGÔGÑGÔG€NÝ˜^Ñ,Ô,Ð,Ð,Ð,r*   c                  ó`   — t          d„ t          D ¦   «         ¦  «        } t          | ¦  «         dS )z7Configure SMS (Twilio) via the standard platform setup.c              3   ó2   K  — | ]}|d          dk    ¯|V — ŒdS )rÍ   rú  Nr   rˆ  s     r(   r™   z_setup_sms.<locals>.<genexpr>s  s0   è è € ÐCÐC˜a°°5´¸UÒ1BÐ1B˜Ð1BÐ1BÐ1BÐ1BÐCÐCr*   Nrt  )Úsms_platforms    r(   Ú
_setup_smsr|  q  s2   € åÐCÐC¥:ÐCÑCÔCÑCÔC€LÝ˜\Ñ*Ô*Ð*Ð*Ð*r*   c            	      óš  — ddl m} m}m}m}m} t          d„ t          D ¦   «         ¦  «        }|d         }|d         }t          ¦   «          t          t          d|› d|› d�t          j        ¦  «        ¦  «         t          d	¦  «        }|r1t          ¦   «           ||› d
|› d�¦  «          |d|› d�d¦  «        sdS t          ¦   «           | dddgd¬¦  «        }	|	dk    r¼	 ddlm}
 n6# t          $ r)} |d|› d�¦  «         t!          |¦  «         Y d}~dS d}~ww xY w |
¦   «         }|€ |d¦  «         t!          |¦  «         dS |\  }}t#          d	|¦  «         t#          d|¦  «         t#          dd¦  «         t          ¦   «           ||› d|› d�¦  «         dS t!          |¦  «         t          d	¦  «        rt#          dd¦  «         dS dS )uH   Configure DingTalk â€” QR scan (recommended) or manual credential entry.r   )r   r   r   r   r   c              3   ó2   K  — | ]}|d          dk    ¯|V — ŒdS )rÍ   r   Nr   rˆ  s     r(   r™   z"_setup_dingtalk.<locals>.<genexpr>}  s0   è è € ÐMÐM 1°a¸´hÀ*Ò6LÐ6L˜QÐ6LÐ6LÐ6LÐ6LÐMÐMr*   rÒ  r]   rH  rœ   rI  r  z# is already configured (Client ID: rr  rJ  rK  FNz  Choose setup methodzCQR Code Scan (Recommended, auto-obtain Client ID and Client Secret)z*Manual Input (Client ID and Client Secret)rá  )Údingtalk_qr_authz!  QR auth module failed to load (z ), falling back to manual input.z3  QR auth incomplete, falling back to manual input.r  ÚDINGTALK_ALLOW_ALL_USERSrí  z configured via QR scan!)Úhermes_cli.setupr   r   r   r   r   ru  rv  rÜ   r   r   r]  r	   Úhermes_cli.dingtalk_authr  r  rk  r   )r   r   r   r   r   Údingtalk_platformrÒ  r]   rd  Úmethodr  r  rX   Ú	client_idÚclient_secrets                  r(   Ú_setup_dingtalkr‡  w  s¯  € ðð ð ð ð ð ð ð ð ð ð ð ð ð õ ÐMÐM­
ÐMÑMÔMÑMÔMÐØ˜gÔ&€EØ˜gÔ&€Eå	�G„G€GÝ	�%Ð>˜uÐ>Ð> uÐ>Ð>Ð>ÅÄÑ
LÔ
LÑMÔMÐMåÐ1Ñ2Ô2€HØð Ý‰ŒˆØˆ˜ÐOÐOÀ8ÐOÐOÐOÑPÔPÐPØˆ}Ð6¨eÐ6Ð6Ð6¸Ñ>Ô>ð 	ØˆFå	�G„G€GØˆ]ØàQØ8ð	
ð ðñ ô €Fð �‚{€{ð	ØAÐAÐAÐAÐAÐAÐAøÝð 	ð 	ð 	ØˆMÐc¸cÐcÐcÐcÑdÔdÐdÝ$Ð%6Ñ7Ô7Ð7ØˆFˆFˆFˆFˆFøøøøð	øøøð
 "Ð!Ñ#Ô#ˆØˆ>ØˆMÐOÑPÔPÐPÝ$Ð%6Ñ7Ô7Ð7ØˆFà#)Ñ ˆ	�=ÝÐ+¨YÑ7Ô7Ð7ÝÐ/°Ñ?Ô?Ð?ÝÐ1°6Ñ:Ô:Ð:Ý‰ŒˆØˆ˜Ð@Ð@ Ð@Ð@Ð@ÑAÔAÐAÐAÐAõ 	!Ð!2Ñ3Ô3Ð3åÐ-Ñ.Ô.ð 	?ÝÐ5°vÑ>Ô>Ð>Ð>Ð>ð	?ð 	?s   Ã C' Ã'
DÃ1DÄDc                  ó  — t          ¦   «          t          t          dt          j        ¦  «        ¦  «         t	          d¦  «        } t	          d¦  «        }| r1|r/t          ¦   «          t          d¦  «         t          dd¦  «        sdS t          ¦   «          dd	g}t          d
|d¦  «        }d}d}|dk    ré	 ddlm	} n+# t          $ r}t          d|› �¦  «         d}Y d}~nd}~ww xY w|��	  |¦   «         }nT# t          $ r! t          ¦   «          t          d¦  «         Y dS t          $ r}t          d|› �¦  «         d}Y d}~nd}~ww xY w|r;|                     dd¦  «        }|                     dd¦  «        }t          d¦  «         |r|st          d¦  «         d}d}|r|s t          ¦   «          t          d¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          t!          dd¬¦  «        }|st          d¦  «         dS t!          dd¬¦  «        }|st          d¦  «         dS t#          d|¦  «         t#          d|¦  «         t          ¦   «          t          d¦  «         t          d ¦  «         t!          d!d¬¦  «        }	|	r6|	                     d"d¦  «        }
t#          d#|
¦  «         t          d$¦  «         nÃt          ¦   «          g d%¢}t          d&|d'¦  «        }|dk    r0t#          d(d)¦  «         t#          d*d+¦  «         t          d,¦  «         nj|d'k    r/t#          d(d-¦  «         t          d.¦  «         t          d/¦  «         n5|d0k    r t#          d(d1¦  «         t          d2¦  «         nt          d3¦  «         t          ¦   «          t          d4¦  «         t!          d5d¬¦  «        }|r"t#          d6|¦  «         t          d7|› �¦  «         t          ¦   «          t          d8¦  «         dS )9uH   Interactive setup for WeCom â€” scan QR code or manual credential input.u:     â”€â”€â”€ ðŸ’¬ WeCom (Enterprise WeChat) Setup â”€â”€â”€r  r  zWeCom is already configured.z  Reconfigure WeCom?FNzDScan QR code to obtain Bot ID and Secret automatically (recommended)z)Enter existing Bot ID and Secret manuallyz%  How would you like to set up WeCom?r   )Úqr_scan_for_bot_infoz  WeCom QR scan import failed: z  WeCom setup cancelled.z  QR scan failed: Úbot_idr‰   Úsecretu5     âœ” QR scan successful! Bot ID and Secret obtained.z9  QR scan did not complete. Continuing with manual input.uQ     1. Go to WeCom Application â†’ Workspace â†’ Smart Robot -> Create smart robotsz  2. Select API Modez?  3. Copy the Bot ID and Secret from the bot's credentials infouA     4. The bot connects via WebSocket â€” no public endpoint neededz  Bot IDrM  u0     Skipped â€” WeCom won't work without a Bot ID.z  SecretTu0     Skipped â€” WeCom won't work without a Secret.rL  z8  Enter user IDs to create an allowlist, or leave empty.z.  Allowed user IDs (comma-separated, or empty)rœ   r  rP  )rQ  rR  úDisable direct messagesrS  rT  r`   ÚWECOM_DM_POLICYÚopenrU  rí  rV  ÚpairingrW  rX  rD   Údisabledú  Direct messages disabled.rY  z2  Chat ID for scheduled results and notifications.ú1  Home chat ID (optional, for cron/notifications)r  r\  u   ðŸ’¬ WeCom configured!)rÜ   r   r   r]  r	   r   r   r   Úgateway.platforms.wecomr‰  r±   r   ÚKeyboardInterruptr   r’   r   r   r   r¾  )Úexisting_bot_idÚexisting_secretÚmethod_choicesÚ
method_idxrŠ  r‹  r‰  r  ÚcredentialsÚallowedre  rf  rg  rA  s                 r(   Ú_setup_wecomr›  ²  s×  € å	�G„G€GÝ	�%ÐLÍfÌkÑ
ZÔ
ZÑ[Ô[Ð[å# NÑ3Ô3€OÝ# NÑ3Ô3€OØð ˜?ð Ý‰ŒˆÝÐ4Ñ5Ô5Ð5ÝÐ3°UÑ;Ô;ð 	ØˆFõ 
�G„G€GàNØ3ð€Nõ ÐFÈÐXYÑZÔZ€Jà€FØ€Fà�Q‚€ð	(ØDÐDÐDÐDÐDÐDÐDøÝð 	(ð 	(ð 	(ÝÐ?¸#Ð?Ð?Ñ@Ô@Ð@Ø#'Ð Ð Ð Ð Ð Ð øøøøð	(øøøð  Ð+ð#Ø2Ð2Ñ4Ô4��øÝ$ð ð ð Ý‘”�ÝÐ8Ñ9Ô9Ð9Ø��Ýð #ð #ð #ÝÐ8°3Ð8Ð8Ñ9Ô9Ð9Ø"������øøøøð#øøøð ð WØ$Ÿš¨°2Ñ6Ô6�Ø$Ÿš¨°2Ñ6Ô6�ÝÐUÑVÔVÐVàð 	˜Vð 	ÝÐRÑSÔSÐSØˆFØˆFð ð ˜ð Ý‰ŒˆÝÐfÑgÔgÐgÝÐ)Ñ*Ô*Ð*ÝÐTÑUÔUÐUÝÐVÑWÔWÐWÝ‰ŒˆÝ˜
¨UÐ3Ñ3Ô3ˆØð 	ÝÐLÑMÔMÐMØˆFÝ˜
¨TÐ2Ñ2Ô2ˆØð 	ÝÐLÑMÔMÐMØˆFõ �> 6Ñ*Ô*Ð*Ý�> 6Ñ*Ô*Ð*õ 
�G„G€GÝÐHÑIÔIÐIÝÐIÑJÔJÐJÝÐEÐPUÐVÑVÔV€GØð TØ—/’/ # rÑ*Ô*ˆÝÐ,¨gÑ6Ô6Ð6ÝÐOÑPÔPÐPÐPå‰Œˆð
ð 
ð 
ˆõ #Ð#PÐR`ÐbcÑdÔdˆ
Ø˜Š?ˆ?ÝÐ,¨fÑ5Ô5Ð5ÝÐ4°fÑ=Ô=Ð=ÝÐNÑOÔOÐOÐOØ˜1Š_ˆ_ÝÐ,¨iÑ8Ô8Ð8ÝÐ^Ñ_Ô_Ð_ÝÐQÑRÔRÐRÐRØ˜1Š_ˆ_ÝÐ,¨jÑ9Ô9Ð9ÝÐ7Ñ8Ô8Ð8Ð8åÐRÑSÔSÐSõ 
�G„G€GÝÐCÑDÔDÐDÝÐEÐPUÐVÑVÔV€DØð 7ÝÐ+¨TÑ2Ô2Ð2ÝÐ5¨tÐ5Ð5Ñ6Ô6Ð6å	�G„G€GÝÐ*Ñ+Ô+Ð+Ð+Ð+s6   Â5B< Â<
C$ÃCÃC$Ã*
C5 Ã5'EÄ	EÄ(EÅEc                  ó  — t          ¦   «         rDt          d¬¦  «                             ¦   «         p!t          d¬¦  «                             ¦   «         S t          ¦   «         r t	          ¦   «                              ¦   «         S dS )z6Check if the gateway is installed as a system service.Fr¶   T)rF   r»   r¼   rR   rô   r   r*   r(   Ú_is_service_installedr�  '  st   € å Ñ"Ô"ð 1Ý$¨EÐ2Ñ2Ô2×9Ò9Ñ;Ô;ÐjÕ?TÐ\`Ð?aÑ?aÔ?a×?hÒ?hÑ?jÔ?jÐjÝ	‰Œð 1Ý%Ñ'Ô'×.Ò.Ñ0Ô0Ð0Øˆ5r*   c                  ó\  — t          ¦   «         �rt          d¬¦  «                             ¦   «         } t          d¬¦  «                             ¦   «         }| r_	 t          dt	          ¦   «         gdddd¬¦  «        }|j                             ¦   «         dk    rdS n# t          t          j	        f$ r Y nw xY w|r_	 t          dt	          ¦   «         gdddd¬¦  «        }|j                             ¦   «         dk    rdS n# t          t          j	        f$ r Y nw xY wdS t          ¦   «         rit          ¦   «                              ¦   «         rI	 t          j        dd	t          ¦   «         gddd¬
¦  «        }|j        dk    S # t          j	        $ r Y dS w xY wt          t!          ¦   «         ¦  «        dk    S )z2Check if the gateway service is currently running.Fr¶   Tr·   r“   r¸   r¹   rA   rB   r:   r   )rF   r»   r¼   r½   r¾   rI   rJ   r¿   rG   rP   rR   rô   rH   rS   rT   rU   r³   )Úuser_unit_existsÚsystem_unit_existsrX   s      r(   Ú_is_service_runningr¡  0  s	  € å Ñ"Ô"ñ #Ý0¸Ð>Ñ>Ô>×EÒEÑGÔGÐÝ2¸$Ð?Ñ?Ô?×FÒFÑHÔHÐàð 		ðÝ'Ø Õ"2Ñ"4Ô"4Ð5Ø °¸DÈ"ðñ ô �ð ”=×&Ò&Ñ(Ô(¨HÒ4Ð4Ø˜4ð 5øå ¥*Ô";Ð<ð ð ð Ø�ðøøøð ð 		ðÝ'Ø Õ"2Ñ"4Ô"4Ð5Ø°¸4Èðñ ô �ð ”=×&Ò&Ñ(Ô(¨HÒ4Ð4Ø˜4ð 5øå ¥*Ô";Ð<ð ð ð Ø�ðøøøð ˆuÝ	‰Œð Õ.Ñ0Ô0×7Ò7Ñ9Ô9ð ð	Ý”^Ø˜fÕ&7Ñ&9Ô&9Ð:Ø#¨$¸ðñ ô ˆFð Ô$¨Ò)Ð)øÝÔ(ð 	ð 	ð 	Ø�5�5ð	øøøõ Õ Ñ"Ô"Ñ#Ô# aÒ'Ð's6   Á?B ÂB2Â1B2Â8?C: Ã:DÄDÅ1E9 Å9FÆFc                  ó$  — t          ¦   «          t          t          dt          j        ¦  «        ¦  «         t          ¦   «          t	          d¦  «         t	          d¦  «         t	          d¦  «         t	          d¦  «         t          d¦  «        } t          d¦  «        }| r1|r/t          ¦   «          t          d¦  «         t          d	d
¦  «        sdS 	 ddlm	}m
} n9# t          $ r,}t          d|› �¦  «         t	          d¦  «         Y d}~dS d}~ww xY w |¦   «         s t          d¦  «         t	          d¦  «         dS t          ¦   «          t          dd¦  «        st	          d¦  «         dS ddl}	  |j         |t          t!          ¦   «         ¦  «        ¦  «        ¦  «        }nS# t"          $ r! t          ¦   «          t%          d¦  «         Y dS t          $ r}t          d|› �¦  «         Y d}~dS d}~ww xY w|st%          d¦  «         dS |                     dd¦  «        }|                     dd¦  «        }|                     dd¦  «        }	|                     dd¦  «        }
t)          d|¦  «         t)          d|¦  «         |	rt)          d|	¦  «         t)          dt          d¦  «        pd¦  «         t          ¦   «          g d ¢}t+          d!|d¦  «        }|dk    rOt)          d"d#¦  «         t)          d$d%¦  «         t)          d&d¦  «         t          d'¦  «         t	          d(¦  «         nõ|d)k    r@t)          d"d*¦  «         t)          d$d+¦  «         t)          d&d¦  «         t%          d,¦  «         n¯|d-k    rj|
pd}t-          d.|d
¬/¦  «                             d0d¦  «        }t)          d"d1¦  «         t)          d$d%¦  «         t)          d&|¦  «         t          d2¦  «         n?t)          d"d3¦  «         t)          d$d%¦  «         t)          d&d¦  «         t%          d4¦  «         t          ¦   «          g d5¢}t+          d6|d¦  «        }|dk    r0t)          d7d3¦  «         t)          d8d¦  «         t	          d9¦  «         n‹|d)k    r0t)          d7d*¦  «         t)          d8d¦  «         t%          d:¦  «         nUt-          d;dd
¬/¦  «                             d0d¦  «        }t)          d7d1¦  «         t)          d8|¦  «         t          d<¦  «         |
rDt          ¦   «          t          d=|
› d>�d¦  «        r"t)          d?|
¦  «         t          d@|
› �¦  «         t          ¦   «          t          dA¦  «         t	          dB|› �¦  «         |
rt	          dC|
› �¦  «         dS dS )Dz8Interactive setup for Weixin / WeChat personal accounts.u0     â”€â”€â”€ ðŸ’¬ Weixin / WeChat Setup â”€â”€â”€z>  1. Hermes will open Tencent iLink QR login in this terminal.z0  2. Use WeChat to scan and confirm the QR code.zG  3. Hermes will store the returned account_id/token in ~/.hermes/.env.zL  4. This adapter supports native text, image, video, and document delivery.r  r+  zWeixin is already configured.z  Reconfigure Weixin?FNr   )Úcheck_weixin_requirementsÚqr_loginz   Weixin adapter import failed: z1  Install gateway dependencies first, then retry.z>  Missing dependencies: Weixin needs aiohttp and cryptography.z2  Install them, then rerun `hermes gateway setup`.z  Start QR login now?Tz  Cancelled.z  Weixin setup cancelled.z  QR login failed: z  QR login did not complete.Ú
account_idr‰   r4  Úbase_urlÚuser_idÚWEIXIN_BASE_URLÚWEIXIN_CDN_BASE_URLz%https://novac2c.cdn.weixin.qq.com/c2c)ú%Use DM pairing approval (recommended)úAllow all direct messagesúOnly allow listed user IDsrŒ  ú+  How should direct messages be authorized?ÚWEIXIN_DM_POLICYr�  ÚWEIXIN_ALLOW_ALL_USERSrð  ÚWEIXIN_ALLOWED_USERSú  DM pairing enabled.zY  Unknown DM users can request access and you approve them with `hermes pairing approve`.r`   rŽ  rí  z$  Open DM access enabled for Weixin.rD   z+  Allowed Weixin user IDs (comma-separated)rM  rœ   Ú	allowlistz  Weixin allowlist saved.r�  r‘  )z!Disable group chats (recommended)zAllow all group chatsz Only allow listed group chat IDsú$  How should group chats be handled?ÚWEIXIN_GROUP_POLICYÚWEIXIN_GROUP_ALLOWED_USERSú  Group chats disabled.z  All group chats enabled.z*  Allowed group chat IDs (comma-separated)z  Group allowlist saved.z  Use your Weixin user ID (r[  ÚWEIXIN_HOME_CHANNELr\  zWeixin configured!z  Account ID: z  User ID: )rÜ   r   r   r]  r   r	   r   r   Úgateway.platforms.weixinr£  r¤  r±   r   rÇ  rH   r0   r
   r”  r   r’   r   r   r   r¾  )Úexisting_accountra  r£  r¤  r  rÇ  r™  r¥  r4  r¦  r§  rf  rg  Údefault_allowr²  Úgroup_choicesÚ	group_idxÚallow_groupss                     r(   Ú_setup_weixinr¾  Z  sa  € å	�G„G€GÝ	�%ÐBÅFÄKÑ
PÔ
PÑQÔQÐQÝ	�G„G€GÝÐOÑPÔPÐPÝÐAÑBÔBÐBÝÐXÑYÔYÐYÝÐ]Ñ^Ô^Ð^å$Ð%8Ñ9Ô9ÐÝ" >Ñ2Ô2€NØð ˜Nð Ý‰ŒˆÝÐ5Ñ6Ô6Ð6ÝÐ4°eÑ<Ô<ð 	ØˆFðØPÐPÐPÐPÐPÐPÐPÐPÐPøÝð ð ð ÝÐ<°sÐ<Ð<Ñ=Ô=Ð=ÝÐFÑGÔGÐGØˆˆˆˆˆøøøøðøøøð
 %Ð$Ñ&Ô&ð ÝÐTÑUÔUÐUÝÐGÑHÔHÐHØˆå	�G„G€GÝÐ0°$Ñ7Ô7ð Ý�>Ñ"Ô"Ð"Øˆà€N€N€NðØ!�g”k ( (­3­Ñ/@Ô/@Ñ+AÔ+AÑ"BÔ"BÑCÔCˆˆøÝð ð ð Ý‰ŒˆÝÐ1Ñ2Ô2Ð2ØˆˆÝð ð ð ÝÐ/¨#Ð/Ð/Ñ0Ô0Ð0Øˆˆˆˆˆøøøøðøøøð ð ÝÐ4Ñ5Ô5Ð5Øˆà—’ ¨rÑ2Ô2€JØ�OŠO˜G RÑ(Ô(€EØ�Š˜z¨2Ñ.Ô.€HØ�oŠo˜i¨Ñ,Ô,€GåÐ&¨
Ñ3Ô3Ð3Ý�> 5Ñ)Ô)Ð)Øð 4ÝÐ(¨(Ñ3Ô3Ð3ÝÐ(­-Ð8MÑ*NÔ*NÐ*yÐRyÑzÔzÐzå	�G„G€Gðð ð €Nõ ÐLÈnÐ^_Ñ`Ô`€JØ�Q‚€ÝÐ)¨9Ñ5Ô5Ð5ÝÐ/°Ñ9Ô9Ð9ÝÐ-¨rÑ2Ô2Ð2ÝÐ-Ñ.Ô.Ð.ÝÐnÑoÔoÐoÐoØ	�qŠˆÝÐ)¨6Ñ2Ô2Ð2ÝÐ/°Ñ8Ô8Ð8ÝÐ-¨rÑ2Ô2Ð2ÝÐ<Ñ=Ô=Ð=Ð=Ø	�qŠˆØ˜ 2ˆÝÐHÈ-ÐbgÐhÑhÔh×pÒpÐqtÐvxÑyÔyˆ	ÝÐ)¨;Ñ7Ô7Ð7ÝÐ/°Ñ9Ô9Ð9ÝÐ-¨yÑ9Ô9Ð9ÝÐ1Ñ2Ô2Ð2Ð2åÐ)¨:Ñ6Ô6Ð6ÝÐ/°Ñ9Ô9Ð9ÝÐ-¨rÑ2Ô2Ð2ÝÐ3Ñ4Ô4Ð4å	�G„G€Gðð ð €Mõ
 ÐDÀmÐUVÑWÔW€IØ�A‚~€~ÝÐ,¨jÑ9Ô9Ð9ÝÐ3°RÑ8Ô8Ð8ÝÐ,Ñ-Ô-Ð-Ð-Ø	�aŠˆÝÐ,¨fÑ5Ô5Ð5ÝÐ3°RÑ8Ô8Ð8ÝÐ2Ñ3Ô3Ð3Ð3åÐJÈBÐY^Ð_Ñ_Ô_×gÒgÐhkÐmoÑpÔpˆÝÐ,¨kÑ:Ô:Ð:ÝÐ3°\ÑBÔBÐBÝÐ0Ñ1Ô1Ð1àð >Ý‰ŒˆÝÐV°wÐVÐVÐVÐX\Ñ]Ô]ð 	>ÝÐ0°'Ñ:Ô:Ð:ÝÐ<°7Ð<Ð<Ñ=Ô=Ð=å	�G„G€GÝÐ&Ñ'Ô'Ð'ÝÐ, 
Ð,Ð,Ñ-Ô-Ð-Øð ,ÝÐ* Ð*Ð*Ñ+Ô+Ð+Ð+Ð+ð,ð ,s6   ÃC Ã
DÃ%!DÄDÅ22F% Æ%'G5Ç	G5ÇG0Ç0G5c                  ó*  — t          ¦   «          t          t          dt          j        ¦  «        ¦  «         t	          d¦  «        } t	          d¦  «        }| r1|r/t          ¦   «          t          d¦  «         t          dd¦  «        sdS t          ¦   «          dd	g}t          d
|d¦  «        }d}d}|dk    r¨	 ddlm	} n+# t          $ r}t          d|› �¦  «         d}Y d}~nd}~ww xY w|�^	  |¦   «         }nR# t          $ r! t          ¦   «          t          d¦  «         Y dS t          $ r}t          d|› �¦  «         Y d}~nd}~ww xY w|rd}|st          d¦  «         |�s$t          ¦   «          t          d¦  «         t          d¦  «         t          ¦   «          t          dd¬¦  «        }|st          d¦  «         dS t          dd¬¦  «        }	|	st          d¦  «         dS ddg}
t          d|
d¦  «        }|dk    rdnd}d}	 ddlm}  |||	|¦  «        }|r*|                     d ¦  «        }t          d!|pd"› �¦  «         nt          d#¦  «         n)# t          $ r}t          d$|› �¦  «         Y d}~nd}~ww xY w||	|d|d%œ}|d&         }|d'         }	|                     d(d¦  «        }|                     d)¦  «        }|                     d ¦  «        }t%          d|¦  «         t%          d|	¦  «         t%          d*|¦  «         |rd+}n`t          ¦   «          d,d-g}t          d.|d¦  «        }|dk    rd/nd+}|d/k    r-t          d0¦  «         t          d1¦  «         t          d2¦  «         t%          d3|¦  «         |r t          ¦   «          t          d4|› �¦  «         t          ¦   «          g d5¢}t          d6|d¦  «        }|dk    r?t%          d7d8¦  «         t%          d9d:¦  «         t          d;¦  «         t          d<¦  «         n�|dk    r0t%          d7d=¦  «         t%          d9d:¦  «         t          d>¦  «         nYt%          d7d8¦  «         |pd:}t          d?|d¬¦  «                             d@d:¦  «        }t%          d9|¦  «         t          dA¦  «         t          ¦   «          dBdCg}t          dD|d¦  «        }|dk    r t%          dEdF¦  «         t          dG¦  «         nt%          dEdH¦  «         t          dI¦  «         t          ¦   «          t          dJd¬¦  «        }|r"t%          dK|¦  «         t          dL|› �¦  «         t          ¦   «          t          dM¦  «         t          dN|› �¦  «         t          dO|› �¦  «         |rt          dP|› �¦  «         dS dS )QuM   Interactive setup for Feishu / Lark â€” scan-to-create or manual credentials.u.     â”€â”€â”€ ðŸª½ Feishu / Lark Setup â”€â”€â”€r  r  z$Feishu / Lark is already configured.z  Reconfigure Feishu / Lark?FNz<Scan QR code to create a new bot automatically (recommended)ú-Enter existing App ID and App Secret manuallyz-  How would you like to set up Feishu / Lark?r   ©Úqr_registerz'  Feishu / Lark onboard import failed: z   Feishu / Lark setup cancelled.z  QR registration failed: Tú:  QR setup did not complete. Continuing with manual input.zI  Go to https://open.feishu.cn/ (or https://open.larksuite.com/ for Lark)zE  Create an app, enable the Bot capability, and copy the credentials.ú  App IDrM  u9     Skipped â€” Feishu / Lark won't work without an App ID.ú  App Secretu=     Skipped â€” Feishu / Lark won't work without an App Secret.zfeishu (China)zlark (International)z  Domainr`   Úlarkr  )Ú	probe_botÚbot_nameu      Credentials verified â€” bot: Úunnamedz<  Could not verify bot connection. Credentials saved anyway.z#  Credential verification skipped: )Úapp_idÚ
app_secretÚdomainÚopen_idrÈ  rÊ  rË  rÌ  rÍ  r  Ú	websocketu0   WebSocket (recommended â€” no public URL needed)z,Webhook (requires a reachable HTTP endpoint)z  Connection modeÚwebhookz1  Webhook defaults: 127.0.0.1:8765/feishu/webhookzO  Override with FEISHU_WEBHOOK_HOST / FEISHU_WEBHOOK_PORT / FEISHU_WEBHOOK_PATHzR  For signature verification, set FEISHU_ENCRYPT_KEY and FEISHU_VERIFICATION_TOKENr  z  Bot created: )rª  r«  r¬  r­  ÚFEISHU_ALLOW_ALL_USERSrð  r	  r‰   r±  úJ  Unknown users can request access; approve with `hermes pairing approve`.rí  z+  Open DM access enabled for Feishu / Lark.z$  Allowed user IDs (comma-separated)rœ   ú  Allowlist saved.z4Respond only when @mentioned in groups (recommended)zDisable group chatsr³  ÚFEISHU_GROUP_POLICYrŽ  z/  Group chats enabled (bot must be @mentioned).r�  r¶  r’  r
  r\  u   ðŸª½ Feishu / Lark configured!ú
  App ID: z
  Domain: z  Bot: )rÜ   r   r   r]  r	   r   r   r   Úgateway.platforms.feishurÂ  r±   r   r”  r   r   r   rÇ  r’   r   r¾  )Úexisting_app_idr–  r—  r˜  r™  Úused_qrrÂ  r  rÊ  rË  Údomain_choicesÚ
domain_idxrÌ  rÈ  rÇ  Úbot_inforÍ  Úconnection_modeÚmode_choicesÚmode_idxrf  rg  rº  r²  r»  r¼  Úhome_channels                              r(   Ú_setup_feishurß  Ù  s  € å	�G„G€GÝ	�%Ð@Å&Ä+Ñ
NÔ
NÑOÔOÐOå# OÑ4Ô4€OÝ#Ð$7Ñ8Ô8€OØð ˜?ð Ý‰ŒˆÝÐ<Ñ=Ô=Ð=ÝÐ;¸UÑCÔCð 	ØˆFõ 
�G„G€GàFØ7ð€Nõ ÐNÐP^Ð`aÑbÔb€Jà€KØ€Gà�Q‚€ð	Ø<Ð<Ð<Ð<Ð<Ð<Ð<øÝð 	ð 	ð 	ÝÐGÀ#ÐGÐGÑHÔHÐHØˆKˆKˆKˆKˆKˆKøøøøð	øøøð Ð"ðBØ)˜k™mœm��øÝ$ð ð ð Ý‘”�ÝÐ@ÑAÔAÐAØ��Ýð Bð Bð BÝÐ@¸3Ð@Ð@ÑAÔAÐAÐAÐAÐAÐAÐAøøøøðBøøøàð 	ØˆGØð 	UÝÐSÑTÔTÐTð ñ %
Ý‰ŒˆÝÐ^Ñ_Ô_Ð_ÝÐZÑ[Ô[Ð[Ý‰ŒˆÝ˜
¨UÐ3Ñ3Ô3ˆØð 	ÝÐUÑVÔVÐVØˆFÝ˜N°TÐ:Ñ:Ô:ˆ
Øð 	ÝÐYÑZÔZÐZØˆFà*Ð,BÐCˆÝ" :¨~¸qÑAÔAˆ
Ø%¨š?˜?��°ˆð ˆð		GØ:Ð:Ð:Ð:Ð:Ð:Ø �y ¨°VÑ<Ô<ˆHØð ^Ø#Ÿ<š<¨
Ñ3Ô3�ÝÐXÀÐAVÈYÐXÐXÑYÔYÐYÐYåÐ\Ñ]Ô]Ð]øøÝð 	Gð 	Gð 	GÝÐEÀÐEÐEÑFÔFÐFÐFÐFÐFÐFÐFøøøøð	Gøøøð Ø$ØØØ ð
ð 
ˆð ˜Ô"€FØ˜\Ô*€JØ�_Š_˜X xÑ0Ô0€FØ�oŠo˜iÑ(Ô(€GØ�Š˜zÑ*Ô*€Hå�? FÑ+Ô+Ð+ÝÐ&¨
Ñ3Ô3Ð3Ý�? FÑ+Ô+Ð+ð ð mØ%ˆˆå‰Œˆà>Ø:ð
ˆõ !Ð!4°lÀAÑFÔFˆØ'/°1¢} }˜)˜)¸+ˆØ˜iÒ'Ð'ÝÐJÑKÔKÐKÝÐhÑiÔiÐiÝÐkÑlÔlÐlÝÐ+¨_Ñ=Ô=Ð=àð 4Ý‰ŒˆÝÐ2¨Ð2Ð2Ñ3Ô3Ð3õ 
�G„G€Gðð ð €Nõ
 ÐLÈnÐ^_Ñ`Ô`€JØ�Q‚€ÝÐ/°Ñ9Ô9Ð9ÝÐ-¨rÑ2Ô2Ð2ÝÐ-Ñ.Ô.Ð.ÝÐ_Ñ`Ô`Ð`Ð`Ø	�qŠˆÝÐ/°Ñ8Ô8Ð8ÝÐ-¨rÑ2Ô2Ð2ÝÐCÑDÔDÐDÐDåÐ/°Ñ9Ô9Ð9Ø˜ 2ˆÝÐAÀ=Ð[`ÐaÑaÔa×iÒiÐjmÐoqÑrÔrˆ	ÝÐ-¨yÑ9Ô9Ð9ÝÐ*Ñ+Ô+Ð+õ 
�G„G€Gà>Øð€Mõ ÐDÀmÐUVÑWÔW€IØ�A‚~€~ÝÐ,¨fÑ5Ô5Ð5ÝÐDÑEÔEÐEÐEåÐ,¨jÑ9Ô9Ð9ÝÐ,Ñ-Ô-Ð-õ 
�G„G€GÝÐMÐX]Ð^Ñ^Ô^€LØð ?ÝÐ,¨lÑ;Ô;Ð;ÝÐ=¨|Ð=Ð=Ñ>Ô>Ð>å	�G„G€GÝÐ2Ñ3Ô3Ð3ÝÐ$˜FÐ$Ð$Ñ%Ô%Ð%ÝÐ$˜FÐ$Ð$Ñ%Ô%Ð%Øð )ÝÐ'˜XÐ'Ð'Ñ(Ô(Ð(Ð(Ð(ð)ð )sO   Â5B< Â<
C$ÃCÃC$Ã*
C5 Ã5'EÄ	EÄ(D?Ä?EÈAI É
I8ÉI3É3I8c                  óZ  — t          ¦   «          t          t          dt          j        ¦  «        ¦  «         t	          d¦  «        } t	          d¦  «        }| r1|r/t          ¦   «          t          d¦  «         t          dd¦  «        sdS t          ¦   «          dd	g}t          d
|d¦  «        }d}d}|dk    rU	 ddlm	}  |¦   «         }n.# t          $ r! t          ¦   «          t          d¦  «         Y dS w xY w|rd}|st          d¦  «         |s¬t          ¦   «          t          d¦  «         t          d¦  «         t          ¦   «          t          dd¬¦  «        }|st          d¦  «         dS t          dd¬¦  «        }|st          d¦  «         dS |                     ¦   «         |                     ¦   «         ddœ}t          d|d         ¦  «         t          d|d         ¦  «         |                     dd¦  «        }	t          ¦   «          g d¢}
t          d|
d¦  «        }|dk    r—t          dd¦  «         |	rVt          ¦   «          t          d |	› d!�d¦  «        r#t          d"|	¦  «         t          d#|	› �¦  «         n!t          d"d¦  «         nt          d"d¦  «         t          d$¦  «         t          d%¦  «         n�|d&k    r0t          dd'¦  «         t          d"d¦  «         t          d(¦  «         nY|	pd}t          d)|d¬¦  «                             d*d¦  «        }t          dd¦  «         t          d"|¦  «         t          d+¦  «         |	rEt          ¦   «          t          d,|	› d-�d¦  «        r"t          d.|	¦  «         t          d/|	› �¦  «         ngt          ¦   «          t          d0d¬¦  «        }|rFt          d.|                     ¦   «         ¦  «         t          d/|                     ¦   «         › �¦  «         t          ¦   «          t          d1¦  «         t          d2|d         › �¦  «         dS )3uI   Interactive setup for QQ Bot â€” scan-to-configure or manual credentials.u'     â”€â”€â”€ ðŸ�§ QQ Bot Setup â”€â”€â”€r!  r"  zQQ Bot is already configured.z  Reconfigure QQ Bot?FNz3Scan QR code to add bot automatically (recommended)rÀ  z&  How would you like to set up QQ Bot?r   rÁ  z  QQ Bot setup cancelled.TrÃ  z:  Go to https://q.qq.com to register a QQ Bot application.z<  Note your App ID and App Secret from the application page.rÄ  rM  u2     Skipped â€” QQ Bot won't work without an App ID.rÅ  u6     Skipped â€” QQ Bot won't work without an App Secret.r‰   )rÊ  r†  Úuser_openidrÊ  r†  rá  )rª  r«  zOnly allow listed user OpenIDsr­  ÚQQ_ALLOW_ALL_USERSrð  z  Add yourself (z) to the allow list?r#  z  Allow list set to r±  rÑ  r`   rí  z$  Open DM access enabled for QQ Bot.z(  Allowed user OpenIDs (comma-separated)rœ   rÒ  z  Use your QQ user ID (r[  r$  r\  z8  Home channel OpenID (for cron/notifications, or empty)u   ðŸ�§ QQ Bot configured!rÔ  )rÜ   r   r   r]  r	   r   r   r   Úgateway.platforms.qqbotrÂ  r”  r   r   r   rJ   r   r’   r¾  )rÖ  r–  r—  r˜  r™  r×  rÂ  rÊ  rË  rá  rf  rg  rº  r²  rÞ  s                  r(   Ú_setup_qqboträ  …  sÉ  € å	�G„G€GÝ	�%Ð9½6¼;Ñ
GÔ
GÑHÔHÐHå# KÑ0Ô0€OÝ#Ð$6Ñ7Ô7€OØð ˜?ð Ý‰ŒˆÝÐ5Ñ6Ô6Ð6ÝÐ4°eÑ<Ô<ð 	ØˆFõ 
�G„G€Gà=Ø7ð€Nõ ÐGÈÐYZÑ[Ô[€Jà€KØ€Gà�Q‚€ð	Ø;Ð;Ð;Ð;Ð;Ð;Ø%˜+™-œ-ˆKˆKøÝ ð 	ð 	ð 	Ý‰GŒGˆGÝÐ5Ñ6Ô6Ð6ØˆFˆFð	øøøð ð 	ØˆGØð 	UÝÐSÑTÔTÐTð ð iÝ‰ŒˆÝÐOÑPÔPÐPÝÐQÑRÔRÐRÝ‰ŒˆÝ˜
¨UÐ3Ñ3Ô3ˆØð 	ÝÐNÑOÔOÐOØˆFÝ˜N°TÐ:Ñ:Ô:ˆ
Øð 	ÝÐRÑSÔSÐSØˆFØ!'§¢¡¤À*×BRÒBRÑBTÔBTÐegÐhÐhˆõ �; ¨HÔ 5Ñ6Ô6Ð6ÝÐ% {°?Ô'CÑDÔDÐDà—/’/ -°Ñ4Ô4€Kõ 
�G„G€Gðð ð €Nõ
 ÐLÈnÐ^_Ñ`Ô`€JØ�Q‚€ÝÐ+¨WÑ5Ô5Ð5Øð 	3Ý‰GŒGˆGÝÐQ°ÐQÐQÐQÐSWÑXÔXð 7ÝÐ1°;Ñ?Ô?Ð?ÝÐB°[ÐBÐBÑCÔCÐCÐCåÐ1°2Ñ6Ô6Ð6Ð6åÐ-¨rÑ2Ô2Ð2ÝÐ-Ñ.Ô.Ð.ÝÐ_Ñ`Ô`Ð`Ð`Ø	�qŠˆÝÐ+¨VÑ4Ô4Ð4ÝÐ)¨2Ñ.Ô.Ð.ÝÐ<Ñ=Ô=Ð=Ð=à#Ð) rˆÝÐEÀ}Ð_dÐeÑeÔe×mÒmÐnqÐsuÑvÔvˆ	ÝÐ+¨WÑ5Ô5Ð5ÝÐ)¨9Ñ5Ô5Ð5ÝÐ*Ñ+Ô+Ð+ð ð 
KÝ‰ŒˆÝÐV°;ÐVÐVÐVÐX\Ñ]Ô]ð 	BÝÐ/°Ñ=Ô=Ð=ÝÐ@°;Ð@Ð@ÑAÔAÐAøå‰ŒˆÝÐXÐchÐiÑiÔiˆØð 	KÝÐ/°×1CÒ1CÑ1EÔ1EÑFÔFÐFÝÐI°<×3EÒ3EÑ3GÔ3GÐIÐIÑJÔJÐJå	�G„G€GÝÐ+Ñ,Ô,Ð,ÝÐ3˜K¨Ô1Ð3Ð3Ñ4Ô4Ð4Ð4Ð4s   Â5C Ã'C1Ã0C1c                  ó2
  — ddl } t          ¦   «          t          t          dt          j        ¦  «        ¦  «         t          d¦  «        }t          d¦  «        }|r1|r/t          ¦   «          t          d¦  «         t          dd¦  «        sdS t          ¦   «           | j        d	¦  «        rt          d
¦  «         n£t          d¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          t          ¦   «          t          d¦  «         |pd}	 t          d|› d�¦  «                             ¦   «         p|}n'# t          t          f$ r t          d¦  «         Y dS w xY wt          d¦  «         	 ddl}|                     |                     d¦  «        › d�d¬¦  «        }|j        dk    rt          d¦  «         n*t          d |j        › d!�¦  «         t          d"d¦  «        sdS nB# t&          $ r5}t          d#|› d$|› �¦  «         t          d%d&¦  «        sY d}~dS Y d}~nd}~ww xY wt)          d|¦  «         t          ¦   «          t          d'¦  «         t          d(¦  «         |pd)}	 t          d*|rd+|› d,�nd)› d$�¦  «                             ¦   «         }	|	s|}	n'# t          t          f$ r t          d¦  «         Y dS w xY w|	st+          d-¦  «         dS t)          d|	¦  «         t          ¦   «          t          d.¦  «         t          d/¦  «         t          d0¦  «        pd)}
|
p|	}	 t          d1|› d�¦  «                             ¦   «         p|}n'# t          t          f$ r t          d¦  «         Y dS w xY wt)          d0|¦  «         t          ¦   «          t          d2d¦  «        r’t          ¦   «          t          d3¦  «         t          d4¦  «        pd)}	 t          d5|pd6› d�¦  «                             ¦   «         p|pd6}n'# t          t          f$ r t          d¦  «         Y dS w xY wt)          d4|¦  «         t          ¦   «          t          d7¦  «         t          d8|› �¦  «         t          d9|	› �¦  «         t          d:¦  «         t          d;t          d4¦  «        rd<nd=› �¦  «         dS )>z'Interactive setup for Signal messenger.r   Nu'     â”€â”€â”€ ðŸ“¡ Signal Setup â”€â”€â”€rò  r'  zSignal is already configured.z  Reconfigure Signal?Fz
signal-clizsignal-cli found on PATH.zsignal-cli not found on PATH.z7  Signal requires signal-cli running as an HTTP daemon.z  Install options:zF    Linux:  download from https://github.com/AsamK/signal-cli/releasesz#    macOS:  brew install signal-cliz)    Docker: bbernhard/signal-cli-rest-apiz;  After installing, link your account and start the daemon:z$    signal-cli link -n "HermesAgent"zA    signal-cli --account +YOURNUMBER daemon --http 127.0.0.1:8080z8  Enter the URL where signal-cli HTTP daemon is running.zhttp://127.0.0.1:8080z  HTTP URL [z]: z
  Setup cancelled.z  Testing connection...r–  z/api/v1/checkr©  rj  éÈ   z!  signal-cli daemon is reachable!z#  signal-cli responded with status ú.z  Continue anyway?z   Could not reach signal-cli at r  z8  Save this URL anyway? (you can start signal-cli later)Tz9  Enter your Signal account phone number in E.164 format.z  Example: +15551234567r‰   z  Account numberz [ú]z  Account number is required.rL  zB  Enter phone numbers or UUIDs of allowed users (comma-separated).ÚSIGNAL_ALLOWED_USERSz  Allowed users [z<  Enable group messaging? (disabled by default for security)z0  Enter group IDs to allow, or * for all groups.ÚSIGNAL_GROUP_ALLOWED_USERSz  Group IDs [Ú*zSignal configured!z  URL: z  Account: z0  DM auth: via SIGNAL_ALLOWED_USERS + DM pairingz
  Groups: Úenabledr�  )r-  rÜ   r   r   r]  r	   r   r   r.  r   r   ÚinputrJ   ÚEOFErrorr”  Úhttpxr’   r;  Ústatus_coder±   r   r   )r-  Úexisting_urlr¹  Údefault_urlÚurlrï  Úrespr¿  Údefault_accountr/  Úexisting_allowedÚdefault_allowedrš  Úexisting_groupsÚgroupss                  r(   Ú_setup_signalrú  ó  s  € à€M€M€Må	�G„G€GÝ	�%Ð9½6¼;Ñ
GÔ
GÑHÔHÐHå Ð!2Ñ3Ô3€LÝ$Ð%5Ñ6Ô6ÐØð Ð(ð Ý‰ŒˆÝÐ5Ñ6Ô6Ð6ÝÐ4°eÑ<Ô<ð 	ØˆFõ 
�G„G€GØ€v„|�LÑ!Ô!ð ÝÐ1Ñ2Ô2Ð2Ð2åÐ5Ñ6Ô6Ð6ÝÐLÑMÔMÐMÝÐ'Ñ(Ô(Ð(ÝÐ[Ñ\Ô\Ð\ÝÐ8Ñ9Ô9Ð9ÝÐ>Ñ?Ô?Ð?Ý‰ŒˆÝÐPÑQÔQÐQÝÐ;Ñ<Ô<Ð<ÝÐVÑWÔWÐWÝ‰Œˆõ 
�G„G€GÝÐIÑJÔJÐJØÐ9Ð"9€KðÝÐ3 ;Ð3Ð3Ð3Ñ4Ô4×:Ò:Ñ<Ô<ÐKÀˆˆøÝÕ'Ð(ð ð ð ÝÐ$Ñ%Ô%Ð%Øˆˆðøøøõ
 Ð(Ñ)Ô)Ð)ðØˆˆˆØ�yŠy˜CŸJšJ s™OœOÐ:Ð:Ð:ÀDˆyÑIÔIˆØÔ˜sÒ"Ð"ÝÐ=Ñ>Ô>Ð>Ð>åÐSÀÔ@PÐSÐSÐSÑTÔTÐTÝ Ð!5°uÑ=Ô=ð Ø�øøÝð ð ð ÝÐC¸ÐCÐCÀÐCÐCÑDÔDÐDÝÐWÐY]Ñ^Ô^ð 	ØˆFˆFˆFˆFˆFð	ð 	ð 	ð 	ð 	øøøøðøøøõ
 Ð$ cÑ*Ô*Ð*õ 
�G„G€GÝÐJÑKÔKÐKÝÐ(Ñ)Ô)Ð)Ø&Ð,¨"€OðÝÐaÀoÐ+]Ð+B°Ð+BÐ+BÐ+BÐ+BÐ[]ÐaÐaÐaÑbÔb×hÒhÑjÔjˆØð 	&Ø%ˆGøøÝÕ'Ð(ð ð ð ÝÐ$Ñ%Ô%Ð%Øˆˆðøøøð ð ÝÐ3Ñ4Ô4Ð4ØˆåÐ# WÑ-Ô-Ð-õ 
�G„G€GÝÐHÑIÔIÐIÝÐSÑTÔTÐTÝ$Ð%;Ñ<Ô<ÐBÀÐØ&Ð1¨'€OðÝÐ@¨OÐ@Ð@Ð@ÑAÔA×GÒGÑIÔIÐ\È_ˆˆøÝÕ'Ð(ð ð ð ÝÐ$Ñ%Ô%Ð%Øˆˆðøøøõ Ð)¨7Ñ3Ô3Ð3õ 
�G„G€GÝÐSÐUZÑ[Ô[ð 	=Ý‰ŒˆÝÐEÑFÔFÐFÝ'Ð(DÑEÔEÐKÈˆð	ÝÐF¨?Ð+A¸cÐFÐFÐFÑGÔG×MÒMÑOÔOÐiÐSbÐiÐfiˆFˆFøÝÕ+Ð,ð 	ð 	ð 	ÝÐ(Ñ)Ô)Ð)ØˆFˆFð	øøøõ 	Ð3°VÑ<Ô<Ð<å	�G„G€GÝÐ&Ñ'Ô'Ð'Ýˆ˜ˆˆÑÔÐÝÐ&˜WÐ&Ð&Ñ'Ô'Ð'ÝÐAÑBÔBÐBÝÐf­Ð7SÑ)TÔ)TÐd˜I˜IÐZdÐfÐfÑgÔgÐgÐgÐgsa   Å>'F& Æ& G
Ç	G
ÇA4I É
JÉ%JÊJË1L	 Ì	 L-Ì,L-Î'N= Î= O!Ï O!Ñ+Q- Ñ- RÒRc                  ó  — t          ¦   «         rt          d¦  «         dS t          ¦   «          t          t          dt          j        ¦  «        ¦  «         t          t          dt          j        ¦  «        ¦  «         t          t          dt          j        ¦  «        ¦  «         t          t          dt          j        ¦  «        ¦  «         t          t          dt          j        ¦  «        ¦  «         t          t          dt          j        ¦  «        ¦  «         t          ¦   «          t          ¦   «         } t          ¦   «         }t          ¦   «         r*t          ¦   «         rt          ¦   «          t          ¦   «          t          ¦   «         r*t          ¦   «         rt          ¦   «          t          ¦   «          | r|rt          d	¦  «         �n | ràt          d
¦  «         t          dd¦  «        rÀ	 t          ¦   «         rt!          ¦   «          nt#          ¦   «         rt%          ¦   «          n¤# t&          $ rO}t)          d¦  «         t+          |¦  «                             ¦   «         D ]}t          d|› �¦  «         ŒY d}~nPd}~wt.          j        $ r}t)          d|› �¦  «         Y d}~n'd}~ww xY wnt3          d¦  «         t3          d¦  «         	 t          ¦   «          t5          d¦  «         g }t6          D ]2}t9          |¦  «        }|                     |d         › d|› d�¦  «         Œ3|                     d¦  «         t=          d|t?          |¦  «        dz
  ¦  «        }|t?          t6          ¦  «        k    rnÛt6          |         }|d         dk    rtA          ¦   «          n±|d         dk    rtC          ¦   «          n–|d         dk    rtE          ¦   «          n{|d         dk    rtG          ¦   «          n`|d         dk    rtI          ¦   «          nE|d         dk    rtK          ¦   «          n*|d         d k    rtM          ¦   «          ntO          |¦  «         �ŒƒtQ          d!„ t6          D ¦   «         ¦  «        p&tS          d"¦  «        pd# *                    ¦   «         d$k    }	|	�rÉt          ¦   «          t          t          d%t          j+        ¦  «        ¦  «         t          ¦   «         } t          ¦   «         }|rót          d&d¦  «        rá	 t          ¦   «         rtY          ¦   «          n:t#          ¦   «         rt[          ¦   «          nt]          ¦   «          t3          d'¦  «         �n)# t&          $ rP}t)          d(¦  «         t+          |¦  «                             ¦   «         D ]}t          d|› �¦  «         ŒY d}~�nÔd}~wt.          j        $ r}t)          d)|› �¦  «         Y d}~�nªd}~ww xY w�n | rÕt          d*d¦  «        rÃ	 t          ¦   «         rt!          ¦   «          nt#          ¦   «         rt%          ¦   «          �nR# t&          $ rP}t)          d+¦  «         t+          |¦  «                             ¦   «         D ]}t          d|› �¦  «         ŒY d}~�nýd}~wt.          j        $ r}t)          d,|› �¦  «         Y d}~�nÓd}~ww xY w�nÉt          ¦   «          t          ¦   «         st#          ¦   «         �rÉt          ¦   «         rd-nd.}
t_          ¦   «         rd/nd#}t          d0|
› d1|› d2�d¦  «        �rQ	 d}d3}t          ¦   «         rta          d3¬4¦  «        \  }}ntc          d3¬4¦  «         d}t          ¦   «          |rÈt          d5d¦  «        r¸	 t          ¦   «         rt!          |d6k    ¬7¦  «         nt%          ¦   «          n…# t&          $ rO}t)          d+¦  «         t+          |¦  «                             ¦   «         D ]}t          d|› �¦  «         ŒY d}~n1d}~wt.          j        $ r}t)          d,|› �¦  «         Y d}~nd}~ww xY w�nO# t.          j        $ r,}t)          d8|› �¦  «         t3          d9¦  «         Y d}~�nd}~ww xY wt3          d:¦  «         t          ¦   «         rt3          d;¦  «         t3          d<¦  «         nÕt_          ¦   «         r=t3          d=¦  «         t3          d>¦  «         t3          d?¦  «         t3          d@¦  «         nŠte          ¦   «         r@dAdBl3m4} t3          dC¦  «         t3          d>¦  «         t3          dD |¦   «         › dE�¦  «         n<t3          dF¦  «         t3          d>¦  «         nt          ¦   «          t3          dG¦  «         t          ¦   «          dS )Hz<Interactive setup for messaging platforms + gateway service.zrun gateway setupNrÁ  u@   â”‚             âš• Gateway Setup                            â”‚rÂ  u?   â”‚  Configure messaging platforms and the gateway service. â”‚u>   â”‚  Press Ctrl+C at any time to exit.                     â”‚rÃ  z)Gateway service is installed and running.z-Gateway service is installed but not running.z  Start it now?Tu1     Failed to start â€” user systemd not reachable:r°  z  Failed to start: z%Gateway service is not installed yet.z<You'll be offered to install it after configuring platforms.zMessaging Platformsr]   r¢  rÓ   ÚDonezSelect a platform to configure:r`   rÍ   rî  rp   r  r   r  r   r  c              3   ór   K  — | ]2}|d          dk    ¯t          t          |d         ¦  «        ¦  «        V — Œ3dS )rÍ   rî  rÓ  N)r%   r	   rˆ  s     r(   r™   z gateway_setup.<locals>.<genexpr>¸  sQ   è è € ð ð àØˆUŒ8�zÒ!Ð!õ 	�]˜1˜[œ>Ñ*Ô*Ñ+Ô+à!Ð!Ð!Ð!ðð r*   rð  r‰   rí  u®   â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€z)  Restart the gateway to pick up changes?zStart manually: hermes gatewayu0     Restart failed â€” user systemd not reachable:z  Restart failed: z  Start the gateway service?u.     Start failed â€” user systemd not reachable:z  Start failed: rP  rø   z. (note: services may not survive WSL restarts)z  Install the gateway as a z	 service?z% (runs in background, starts on boot)Fr  z  Start the service now?r´   r¶   z  Install failed: z.  You can try manually: hermes gateway installz/  You can install later: hermes gateway installzA  Or as a boot-time service: sudo hermes gateway install --systemz+  Or run in foreground:  hermes gateway runz*  WSL detected but systemd is not running.z'  Run in foreground: hermes gateway runz<  For persistence:   tmux new -s hermes 'hermes gateway run'zM  To enable systemd: add systemd=true to /etc/wsl.conf, then 'wsl --shutdown'r   rœ  z/  Termux does not use systemd/launchd services.zR  Or start it manually in the background (best effort): nohup hermes gateway run >z/logs/gateway.log 2>&1 &z1  Service install not supported on this platform.z?No platforms configured. Run 'hermes gateway setup' when ready.)5r   r   rÜ   r   r   ÚMAGENTAr�  r¡  rF   rŽ  rÃ  r   r§  r   r   r   ro  rR   r§  rT  r   r0   rK   rG   r¦  r   r   rv  r5  r‚   r   rU   rq  rú  r¾  r‡  rß  rä  r›  rk  r£   r	   rï   ÚDIMrt  rµ  r  r   rè  rŸ  rù   rú   r�  )r   r   r¿  rY   Ú
menu_itemsÚplatr)  râ  r  Úany_configuredÚplatform_nameÚwsl_noteÚinstalled_scopeÚdid_installrž  s                  r(   Úgateway_setupr  e  s8  € å�|„|ð ÝÐ)Ñ*Ô*Ð*Øˆå	�G„G€GÝ	�%ð  Dõ  FLô  FTñ  Uô  Uñ  Vô  Vð  VÝ	�%ÐRÕTZÔTbÑ
cÔ
cÑdÔdÐdÝ	�%ð  Dõ  FLô  FTñ  Uô  Uñ  Vô  Vð  VÝ	�%ÐQÕSYÔSaÑ
bÔ
bÑcÔcÐcÝ	�%ÐPÕRXÔR`Ñ
aÔ
aÑbÔbÐbÝ	�%ð  Dõ  FLô  FTñ  Uô  Uñ  Vô  Vð  Võ 
�G„G€GÝ-Ñ/Ô/ÐÝ)Ñ+Ô+€Oå Ñ"Ô"ð Õ'DÑ'FÔ'Fð Ý,Ñ.Ô.Ð.Ý‰Œˆå Ñ"Ô"ð Õ'>Ñ'@Ô'@ð Ý!Ñ#Ô#Ð#Ý‰Œˆàð S˜_ð SÝÐAÑBÔBÐBÑBØ	ð SÝÐEÑFÔFÐFÝÐ*¨DÑ1Ô1ð 	7ð
7Ý,Ñ.Ô.ð $Ý!‘O”O�O�OÝ‘Z”Zð $Ý!‘O”O�OøøÝ.ð 'ð 'ð 'ÝÐOÑPÔPÐPÝ ™FœF×-Ò-Ñ/Ô/ð 'ð '�DÝ˜+˜t˜+˜+Ñ&Ô&Ð&Ð&ð'ð 'ð 'ð 'ð 'øøøøåÔ0ð 7ð 7ð 7ÝÐ5°!Ð5Ð5Ñ6Ô6Ð6Ð6Ð6Ð6Ð6Ð6øøøøð7øøøð	7õ 	Ð:Ñ;Ô;Ð;ÝÐQÑRÔRÐRð /Ý‰ŒˆÝÐ*Ñ+Ô+Ð+àˆ
Ýð 	>ð 	>ˆDÝ% dÑ+Ô+ˆFØ×Ò  g¤Ð<Ð<°6Ð<Ð<Ð<Ñ=Ô=Ð=Ð=Ø×Ò˜&Ñ!Ô!Ð!åÐ@À*ÍcÐR\ÉoÌoÐ`aÑNaÑbÔbˆà•S�‘_”_Ò$Ð$Øå˜fÔ%ˆà�EŒ?˜jÒ(Ð(ÝÑÔÐÐØ�eŒ_ Ò(Ð(Ý‰OŒOˆOˆOØ�eŒ_ Ò(Ð(Ý‰OŒOˆOˆOØ�eŒ_ 
Ò*Ð*ÝÑÔÐÐØ�eŒ_ Ò(Ð(Ý‰OŒOˆOˆOØ�eŒ_ Ò'Ð'Ý‰NŒNˆNˆNØ�eŒ_ Ò'Ð'Ý‰NŒNˆNˆNå$ XÑ.Ô.Ð.ñA /õF ð ð åðñ ô ñ ô ð Eõ Ð*Ñ
+Ô
+Ð
1¨r×	8Ò	8Ñ	:Ô	:¸fÒ	Dð	 ð ñ VVÝ‰ŒˆÝ�e�J¥¤
Ñ+Ô+Ñ,Ô,Ð,Ý1Ñ3Ô3ÐÝ-Ñ/Ô/ˆàð M	JÝÐHÈ$ÑOÔOð :ð:Ý0Ñ2Ô2ð EÝ'Ñ)Ô)Ð)Ð)Ý!™œð EÝ'Ñ)Ô)Ð)Ð)å,Ñ.Ô.Ð.Ý"Ð#CÑDÔDÐDùøÝ2ð +ð +ð +ÝÐ RÑSÔSÐSÝ # A¡¤× 1Ò 1Ñ 3Ô 3ð +ð +˜Ý˜k 4˜k˜kÑ*Ô*Ð*Ð*ð+ð +ð +ð +ñ +øøøøå!Ô4ð :ð :ð :ÝÐ 8°QÐ 8Ð 8Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ñ9øøøøð:øøøñ:ð ð =	JÝÐ;¸TÑBÔBð 8ð
8Ý0Ñ2Ô2ð (Ý%™œ˜˜Ý!™œð (Ý%™œ˜ùøÝ2ð +ð +ð +ÝÐ PÑQÔQÐQÝ # A¡¤× 1Ò 1Ñ 3Ô 3ð +ð +˜Ý˜k 4˜k˜kÑ*Ô*Ð*Ð*ð+ð +ð +ð +ñ +øøøøå!Ô4ð 8ð 8ð 8ÝÐ 6°1Ð 6Ð 6Ñ7Ô7Ð7Ð7Ð7Ð7Ð7Ñ7øøøøð8øøøñ8õ ‰GŒGˆGÝ(Ñ*Ô*ð .J­h©j¬jñ .JÝ-FÑ-HÔ-HÐ W 	 	Èi�ÝOUÉxÌxÐ_ÐKÐKÐ]_�Ý ð  "G¸}ð  "Gð  "GÐW_ð  "Gð  "Gð  "Gð  IMñ  Nô  Nñ NðUØ*.˜Ø&+˜Ý4Ñ6Ô6ð /Ý;[ÐbgÐ;hÑ;hÔ;hÑ8˜O¨[¨[å+°%Ð8Ñ8Ô8Ð8Ø*.˜KÝ™œ˜Ø&ð D­=Ð9SÐUYÑ+ZÔ+Zð Dð
DÝ#<Ñ#>Ô#>ð !4Ý$1¸ÈHÒ9TÐ$UÑ$UÔ$UÐ$UÐ$Uå$1¡O¤O OøøÝ#>ð 7ð 7ð 7Ý +Ð,\Ñ ]Ô ]Ð ]Ý,/°©F¬F×,=Ò,=Ñ,?Ô,?ð !7ð !7 DÝ$)¨+¨t¨+¨+Ñ$6Ô$6Ð$6Ð$6ð!7ð !7ð !7ð !7ð !7øøøøå#-Ô#@ð Dð Dð DÝ +Ð,B¸qÐ,BÐ,BÑ CÔ CÐ CÐ CÐ CÐ CÐ CÐ CøøøøðDøøøùøå%Ô8ð Uð Uð UÝ#Ð$<¸Ð$<Ð$<Ñ=Ô=Ð=Ý"Ð#SÑTÔTÐTÐTÐTÐTÐTÑTøøøøðUøøøõ ÐPÑQÔQÐQÝ0Ñ2Ô2ð hÝ"Ð#fÑgÔgÐgÝÐLÑMÔMÐMÐMÝ‘”ð JÝÐGÑHÔHÐHÝÐDÑEÔEÐEÝÐYÑZÔZÐZÝÐjÑkÔkÐkÐkå‘;”;ð JØLÐLÐLÐLÐLÐLÝÐPÑQÔQÐQÝÐHÑIÔIÐIÝð   UÐtxÐtxÑtzÔtzð   Uð   Uð   Uñ  Vô  Vð  Vð  VåÐRÑSÔSÐSÝÐHÑIÔIÐIÐIå‰ŒˆÝÐTÑUÔUÐUå	�G„G€G€G€GsÆ   Ç)9H# È#
J%È-AI7É7J%Ê	J Ê J%Ó7AU Õ
WÕAV%Ö%WÖ7W×W×,9X' Ø'
Z+Ø1AY<Ù<Z+ÚZ&Ú&Z+ÜA`* Ý11^# Þ"`* Þ#
`%Þ-A_7ß2`* ß7`%à	` à`* à `%à%`* à*a%à9!a á a%c                 ó  — 	 t          | ¦  «        S # t          $ rd}t          d¦  «         t          |¦  «                             ¦   «         D ]}t          d|› �¦  «         Œt          j        d¦  «         Y d}~dS d}~ww xY w)zHandle gateway subcommands.zUser systemd not reachable:r°  r`   N)Ú_gateway_command_innerrT  r   r0   rK   rÜ   r  rÆ  )r„  r¿  rY   s      r(   Úgateway_commandr
    s–   € ðÝ% dÑ+Ô+Ð+øÝ&ð ð ð õ 	Ð1Ñ2Ô2Ð2Ý˜‘F”F×%Ò%Ñ'Ô'ð 	ð 	ˆDÝ�+�t�+�+ÑÔÐÐÝŒ�‰Œˆˆˆˆˆˆˆøøøøðøøøs   ‚ ‘
A?›AA:Á:A?c           	      ó2!  — t          | dd ¦  «        }|�|dk    rGt          | dd¦  «        }t          | dd¦  «        }t          | dd¦  «        }t          |||¬¦  «         d S |d	k    rt          ¦   «          d S |d
k    �rgt          ¦   «         rt	          d¦  «         d S t          | dd¦  «        }t          | dd¦  «        }t          | dd ¦  «        }t          ¦   «         r2t          d¦  «         t          d¦  «         t          j        d¦  «         t          ¦   «         r]t          ¦   «         r;t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          t          |||¬¦  «         d S t          ¦   «         rt          |¦  «         d S t          ¦   «         r~t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          t          d¦  «         t          d¦  «         t          d¦  «         t          j        d¦  «         d S t!          ¦   «         r}t          d¦  «         t          d¦  «         t          ¦   «          t          d¦  «         t          d¦  «         t          ¦   «          t          d ¦  «         t          j        d¦  «         d S t          d!¦  «         t          d"¦  «         t          j        d¦  «         d S |d#k    �rAt          ¦   «         rt	          d$¦  «         d S t          | dd¦  «        }t          ¦   «         r2t          d%¦  «         t          d&¦  «         t          j        d¦  «         t          ¦   «         rt#          |¬'¦  «         d S t          ¦   «         rt%          ¦   «          d S t!          ¦   «         r`t          d(¦  «         t          d)¦  «         t          ¦   «          t          d*¦  «         t          d+¦  «         t          j        d¦  «         d S t          d,¦  «         t          j        d¦  «         d S |d-k    �r"t          | dd¦  «        }t          | d.d¦  «        }|r6t'          d/¬0¦  «        }	|	r$t          d1|	› d2�¦  «         t)          d3d4¬5¦  «         t          ¦   «         r2t          d6¦  «         t          d¦  «         t          j        d¦  «         t          ¦   «         rt+          |¬'¦  «         d S t          ¦   «         rt-          ¦   «          d S t          ¦   «         rŒt          d7¦  «         t          d8¦  «         t          ¦   «          t          d¦  «         t          d¦  «         t          d¦  «         t          ¦   «          t          d9¦  «         t          j        d¦  «         d S t!          ¦   «         r}t          d:¦  «         t          d;¦  «         t          ¦   «          t          d<¦  «         t          d=¦  «         t          ¦   «          t          d>¦  «         t          j        d¦  «         d S t          d,¦  «         t          j        d¦  «         d S |d?k    �r]t          | d.d¦  «        }
t          | dd¦  «        }|
�rd}t          ¦   «         rmt/          d¬'¦  «                             ¦   «         s"t/          d/¬'¦  «                             ¦   «         r)	 t3          |¬'¦  «         d/}nj# t4          j        $ r Y nYw xY wt          ¦   «         rGt9          ¦   «                              ¦   «         r'	 t;          ¦   «          d/}n# t4          j        $ r Y nw xY wt'          d/¬0¦  «        }	|	|rdndz   }|rt          d@|› dA�¦  «         d S t          dB¦  «         d S d}t          ¦   «         rmt/          d¬'¦  «                             ¦   «         s"t/          d/¬'¦  «                             ¦   «         r)	 t3          |¬'¦  «         d/}nj# t4          j        $ r Y nYw xY wt          ¦   «         rGt9          ¦   «                              ¦   «         r'	 t;          ¦   «          d/}n# t4          j        $ r Y nw xY w|s0t=          ¦   «         rt          dC¦  «         d S t          dD¦  «         d S t          d@t?          ¦   «         › dE�¦  «         d S |dFk    �r)d}t          | dd¦  «        }t          | d.d¦  «        }d}|�rÒd}t          ¦   «         rmt/          d¬'¦  «                             ¦   «         s"t/          d/¬'¦  «                             ¦   «         r)	 t3          |¬'¦  «         d/}nj# t4          j        $ r Y nYw xY wt          ¦   «         rGt9          ¦   «                              ¦   «         r'	 t;          ¦   «          d/}n# t4          j        $ r Y nw xY wt'          d/¬0¦  «        }	|	|rdndz   }|rt          d@|› dA�¦  «         t)          d3d4¬5¦  «         t          dG¦  «         t          ¦   «         rUt/          d¬'¦  «                             ¦   «         s"t/          d/¬'¦  «                             ¦   «         rt+          |¬'¦  «         nMt          ¦   «         r/t9          ¦   «                              ¦   «         rt-          ¦   «          nt          d¬H¦  «         d S t          ¦   «         rot/          d¬'¦  «                             ¦   «         s"t/          d/¬'¦  «                             ¦   «         r+d/}	 tA          |¬'¦  «         d/}nl# t4          j        $ r Y n[w xY wt          ¦   «         rIt9          ¦   «                              ¦   «         r)d/}	 tC          ¦   «          d/}n# t4          j        $ r Y nw xY w|�sUt          ¦   «         r§tE          ¦   «         \  }}|d/ur’dd l#}| $                    ¦   «         }t          ¦   «          t          dI¦  «         t          dJ¦  «         t          ¦   «          t          dK|› �¦  «         t          ¦   «          t          dL¦  «         t          dM¦  «         d S |rOt          ¦   «          t          dN¦  «         t          dO¦  «         t          dP¦  «         t          j        d¦  «         t=          ¦   «         rt          dC¦  «         t)          d3d4¬5¦  «         t          dG¦  «         t          d¬H¦  «         d S d S |dQk    �r=t          | dRd¦  «        }t          | dSd¦  «        }t          | dd¦  «        }tK          |¬'¦  «        }t          ¦   «         rgt/          d¬'¦  «                             ¦   «         s"t/          d/¬'¦  «                             ¦   «         r#tM          |||¬T¦  «         tO          |¦  «         d S t          ¦   «         r@t9          ¦   «                              ¦   «         r tQ          |¦  «         tO          |¦  «         d S tS          |j*        ¦  «        }|�r4t          dUdV +                    tY          tZ          |¦  «        ¦  «        › dW�¦  «         t          dX¦  «         t]          ¦   «         }|r4t          ¦   «          t          dY¦  «         |D ]}t          dZ|› �¦  «         Œt          ¦   «          t          ¦   «         r t          d[¦  «         t          d\¦  «         d S t          ¦   «         r/t          d]¦  «         t          d^¦  «         t          d_¦  «         d S t          d`¦  «         t          da¦  «         t          db¦  «         d S t          dc¦  «         t]          ¦   «         }|r4t          ¦   «          t          dY¦  «         |D ]}t          dZ|› �¦  «         Œt          ¦   «          t          dd¦  «         t          de¦  «         t          ¦   «         rt          df¦  «         d S t          ¦   «         r t          d¦  «         t          d¦  «         d S t          dg¦  «         t          dh¦  «         d S |dik    rct          | djd¦  «        }t          | dkd¦  «        }t          ¦   «         st          ¦   «         st          dl¦  «         d S t_          | |¬m¦  «         d S d S )nNr
  rH   r¼  r   r½  Fr¾  )r½  r¾  Úsetupr\  z*install gateway service (managed by NixOS)r  r´   rÈ  z8Gateway service installation is not supported on Termux.zRun manually: hermes gatewayr`   u?   WSL detected â€” systemd services may not survive WSL restarts.z<  Consider running in foreground instead: hermes gateway runzM  Or use tmux/screen for persistence: tmux new -s hermes 'hermes gateway run'ræ  z(WSL detected but systemd is not running.zIEither enable systemd (add systemd=true to /etc/wsl.conf and restart WSL)z&or run the gateway in foreground mode:zE  hermes gateway run                              # direct foregroundzG  tmux new -s hermes 'hermes gateway run'         # persistent via tmuxzL  nohup hermes gateway run > ~/.hermes/logs/gateway.log 2>&1 &  # backgroundz=Service installation is not needed inside a Docker container.uV   The container runtime is your service manager â€” use Docker restart policies instead:zJ  docker run --restart unless-stopped ...   # auto-restart on crash/rebootz<  docker restart <container>                # manual restartz&To run the gateway: hermes gateway runz4Service installation not supported on this platform.z Run manually: hermes gateway runrk  z,uninstall gateway service (managed by NixOS)zcGateway service uninstall is not supported on Termux because there is no managed service to remove.z*Stop manual runs with: hermes gateway stopr¶   z>Service uninstall is not applicable inside a Docker container.z2To stop the gateway, stop or remove the container:z  docker stop <container>z  docker rm <container>zNot supported on this platform.rí   r,  Tr¯   u   âœ“ Killed z. stale gateway process(es) across all profilesr©  rp  rª  z\Gateway service start is not supported on Termux because there is no system service manager.z*WSL detected but systemd is not available.z+Run the gateway in foreground mode instead:z^To enable systemd: add systemd=true to /etc/wsl.conf and run 'wsl --shutdown' from PowerShell.z:Service start is not applicable inside a Docker container.z1The gateway runs as the container's main process.z:  docker start <container>     # start a stopped containerz<  docker restart <container>   # restart a running containerz/Or run the gateway directly: hermes gateway runrµ  u   âœ“ Stopped z( gateway process(es) across all profilesu   âœ— No gateway processes foundu$   âœ“ Stopped gateway for this profileu'   âœ— No gateway running for this profilez servicers  zStarting gateway...)r¼  uB   âš  Cannot restart gateway as a service â€” linger is not enabled.zK  The gateway user service requires linger to function on headless servers.z$  Run:  sudo loginctl enable-linger rM  z    hermes gateway restartu#   âœ— Gateway service restart failed.zL  The service definition exists, but the service manager did not recover it.z3  Fix the service, then retry: hermes gateway startr)  ru  rv  )r´   rv  u   âœ“ Gateway is running (PID: r  rÓ   z-  (Running manually, not as a system service)rx  r°  zTermux note:z;  Android may stop background jobs when Termux is suspendedz	WSL note:zI  The gateway is running in foreground/manual mode (recommended for WSL).z<  Use tmux or screen for persistence across terminal closes.zTo install as a service:z  hermes gateway installz&  sudo hermes gateway install --systemu   âœ— Gateway is not runningz	To start:z-  hermes gateway run      # Run in foregroundz^  nohup hermes gateway run > ~/.hermes/logs/gateway.log 2>&1 &  # Best-effort background startz3  hermes gateway install  # Install as user servicezM  sudo hermes gateway install --system  # Install as boot-time system servicezmigrate-legacyr©  rì  z@Legacy unit migration only applies to systemd-based Linux hosts.)r¨  r©  )0ÚgetattrrÉ  r  r   r   rù   rÜ   r  rÆ  rF   r   r   r   rç  rR   rŸ  r÷   rm  r¡  r  r¬  ro  r§  r»   r¼   rq  rG   r¦  rô   r®  r  r¾   rt  rµ  ru  rs  rt  rü   r�  r  r»  rB   r    r¥   Úmapr0   r{  rÀ  )r„  Úsubcmdr¼  r½  r¾  r  r´   rÈ  Ú	start_allr  Ústop_allÚservice_availableÚtotalÚrestart_allÚservice_configuredÚservice_stoppedÚ	linger_okÚ_detailrs  Ú	_usernameru  rv  r	  rV   r}  rY   r©  rì  s                               r(   r	  r	  *  sD  € Ý�TÐ,¨dÑ3Ô3€Fð €~˜ 5š˜Ý˜$ 	¨1Ñ-Ô-ˆÝ˜˜g uÑ-Ô-ˆÝ˜$ 	¨5Ñ1Ô1ˆÝ�G 5°'Ð:Ñ:Ô:Ð:Øˆà�ÒÐÝ‰ŒˆØˆð �ÒÑÝ‰<Œ<ð 	ÝÐFÑGÔGÐGØˆFÝ˜˜g uÑ-Ô-ˆÝ˜˜x¨Ñ/Ô/ˆÝ˜d M°4Ñ8Ô8ˆÝ‰;Œ;ð 	ÝÐLÑMÔMÐMÝÐ0Ñ1Ô1Ð1ÝŒH�Q‰KŒKˆKÝ$Ñ&Ô&ð 	Ý‰xŒxð ÝÐ_Ñ`Ô`Ð`ÝÐYÑZÔZÐZÝÐjÑkÔkÐkÝ‘”�Ý %°ÀKÐPÑPÔPÐPÐPÐPÝ‰ZŒZð 	Ý˜EÑ"Ô"Ð"Ð"Ð"Ý‰XŒXð 	ÝÐ<Ñ=Ô=Ð=ÝÐ]Ñ^Ô^Ð^ÝÐ:Ñ;Ô;Ð;Ý‰GŒGˆGÝÐYÑZÔZÐZÝÐ[Ñ\Ô\Ð\ÝÐ`ÑaÔaÐaÝŒH�Q‰KŒKˆKˆKˆKÝ‰^Œ^ð 	ÝÐQÑRÔRÐRÝÐjÑkÔkÐkÝ‰GŒGˆGÝÐ^Ñ_Ô_Ð_ÝÐPÑQÔQÐQÝ‰GŒGˆGÝÐ:Ñ;Ô;Ð;ÝŒH�Q‰KŒKˆKˆKˆKåÐHÑIÔIÐIÝÐ4Ñ5Ô5Ð5ÝŒH�Q‰KŒKˆKˆKˆKà	�;Ò	Ñ	Ý‰<Œ<ð 	ÝÐHÑIÔIÐIØˆFÝ˜˜x¨Ñ/Ô/ˆÝ‰;Œ;ð 	ÝÐwÑxÔxÐxÝÐ>Ñ?Ô?Ð?ÝŒH�Q‰KŒKˆKÝ$Ñ&Ô&ð 	Ý VÐ,Ñ,Ô,Ð,Ð,Ð,Ý‰ZŒZð 	ÝÑÔÐÐÐÝ‰^Œ^ð 		ÝÐRÑSÔSÐSÝÐFÑGÔGÐGÝ‰GŒGˆGÝÐ-Ñ.Ô.Ð.ÝÐ+Ñ,Ô,Ð,ÝŒH�Q‰KŒKˆKˆKˆKåÐ3Ñ4Ô4Ð4ÝŒH�Q‰KŒKˆKˆKˆKà	�7Ò	Ñ	Ý˜˜x¨Ñ/Ô/ˆÝ˜D %¨Ñ/Ô/ˆ	àð 	Få+¸Ð>Ñ>Ô>ˆFØð FÝÐZ FÐZÐZÐZÑ[Ô[Ð[Ý&¨tÀÐEÑEÔEÐEå‰;Œ;ð 	ÝÐpÑqÔqÐqÝÐ0Ñ1Ô1Ð1ÝŒH�Q‰KŒKˆKÝ$Ñ&Ô&ð 	Ý Ð(Ñ(Ô(Ð(Ð(Ð(Ý‰ZŒZð 	Ý‰OŒOˆOˆOˆOÝ‰XŒXð 	ÝÐ>Ñ?Ô?Ð?ÝÐ?Ñ@Ô@Ð@Ý‰GŒGˆGÝÐYÑZÔZÐZÝÐ[Ñ\Ô\Ð\ÝÐ`ÑaÔaÐaÝ‰GŒGˆGÝÐrÑsÔsÐsÝŒH�Q‰KŒKˆKˆKˆKÝ‰^Œ^ð 	ÝÐNÑOÔOÐOÝÐEÑFÔFÐFÝ‰GŒGˆGÝÐNÑOÔOÐOÝÐPÑQÔQÐQÝ‰GŒGˆGÝÐCÑDÔDÐDÝŒH�Q‰KŒKˆKˆKˆKåÐ3Ñ4Ô4Ð4ÝŒH�Q‰KŒKˆKˆKˆKà	�6Ò	Ñ	Ý˜4 ¨Ñ.Ô.ˆÝ˜˜x¨Ñ/Ô/ˆàñ ,	Cà %ÐÝ(Ñ*Ô*ð Õ0EÈUÐ0SÑ0SÔ0S×0ZÒ0ZÑ0\Ô0\ð Õ`uð  ~Bð  aCñ  aCô  aC÷  aJò  aJñ  aLô  aLð ðÝ ¨Ð/Ñ/Ô/Ð/Ø(,Ð%Ð%øÝ!Ô4ð ð ð Ø�Dðøøøå‘”ð Õ 6Ñ 8Ô 8× ?Ò ?Ñ AÔ Að ðÝ ‘N”N�NØ(,Ð%Ð%øÝ!Ô4ð ð ð Ø�Dðøøøå+¸Ð>Ñ>Ô>ˆFØÐ#4Ð;˜a˜a¸!Ñ<ˆEØð 8ÝÐT UÐTÐTÐTÑUÔUÐUÐUÐUåÐ6Ñ7Ô7Ð7Ð7Ð7ð !&ÐÝ(Ñ*Ô*ð Õ0EÈUÐ0SÑ0SÔ0S×0ZÒ0ZÑ0\Ô0\ð Õ`uð  ~Bð  aCñ  aCô  aC÷  aJò  aJñ  aLô  aLð ðÝ ¨Ð/Ñ/Ô/Ð/Ø(,Ð%Ð%øÝ!Ô4ð ð ð Ø�Dðøøøå‘”ð Õ 6Ñ 8Ô 8× ?Ò ?Ñ AÔ Að ðÝ ‘N”N�NØ(,Ð%Ð%øÝ!Ô4ð ð ð Ø�Dðøøøð %ð Cå'Ñ)Ô)ð EÝÐ@ÑAÔAÐAÐAÐAåÐCÑDÔDÐDÐDÐDåÐAÕ%5Ñ%7Ô%7ÐAÐAÐAÑBÔBÐBÐBÐBà	�9Ò	Ñ	à!ÐÝ˜˜x¨Ñ/Ô/ˆÝ˜d E¨5Ñ1Ô1ˆØ"Ðàñ 	à#ˆOÝ(Ñ*Ô*ð Õ0EÈUÐ0SÑ0SÔ0S×0ZÒ0ZÑ0\Ô0\ð Õ`uð  ~Bð  aCñ  aCô  aC÷  aJò  aJñ  aLô  aLð ðÝ ¨Ð/Ñ/Ô/Ð/Ø&*�O�OøÝ!Ô4ð ð ð Ø�Dðøøøå‘”ð Õ 6Ñ 8Ô 8× ?Ò ?Ñ AÔ Að ðÝ ‘N”N�NØ&*�O�OøÝ!Ô4ð ð ð Ø�Dðøøøå+¸Ð>Ñ>Ô>ˆFØ ?Ð9˜a˜a¸Ñ:ˆEØð VÝÐT UÐTÐTÐTÑUÔUÐUÝ"¨4¸SÐAÑAÔAÐAõ Ð'Ñ(Ô(Ð(Ý(Ñ*Ô*ð 'Õ0EÈUÐ0SÑ0SÔ0S×0ZÒ0ZÑ0\Ô0\ð 'Õ`uð  ~Bð  aCñ  aCô  aC÷  aJò  aJñ  aLô  aLð 'Ý VÐ,Ñ,Ô,Ð,Ð,Ý‘”ð 'Õ 6Ñ 8Ô 8× ?Ò ?Ñ AÔ Að 'Ý‘”��å AÐ&Ñ&Ô&Ð&ØˆFå$Ñ&Ô&ð 	Õ,AÈÐ,OÑ,OÔ,O×,VÒ,VÑ,XÔ,Xð 	Õ\qÐy}Ð\~Ñ\~Ô\~÷  ]Fò  ]Fñ  ]Hô  ]Hð 	Ø!%ÐðÝ vÐ.Ñ.Ô.Ð.Ø$(Ð!Ð!øÝÔ0ð ð ð Ø�ðøøøå‰ZŒZð 	Õ2Ñ4Ô4×;Ò;Ñ=Ô=ð 	Ø!%ÐðÝÑ!Ô!Ð!Ø$(Ð!Ð!øÝÔ0ð ð ð Ø�ðøøøð !ñ  	#å(Ñ*Ô*ð Ý%>Ñ%@Ô%@Ñ"�	˜7Ø DÐ(Ð(Ø"�N�N�NØ '§¢Ñ 1Ô 1�IÝ‘G”G�GÝÐ^Ñ_Ô_Ð_ÝÐgÑhÔhÐhÝ‘G”G�GÝÐLÀÐLÐLÑMÔMÐMÝ‘G”G�GÝÐ7Ñ8Ô8Ð8ÝÐ6Ñ7Ô7Ð7Ø�Fà!ð Ý‘”�ÝÐ;Ñ<Ô<Ð<ÝÐdÑeÔeÐeÝÐKÑLÔLÐLÝ”˜‘”�õ $Ñ%Ô%ð >ÝÐ<Ñ=Ô=Ð=å"¨4¸SÐAÑAÔAÐAõ Ð'Ñ(Ô(Ð(Ý Ð"Ñ"Ô"Ð"Ð"Ð"ðA 	#ð  	#ðD 
�8Ò	Ñ	Ý�t˜V UÑ+Ô+ˆÝ�t˜V UÑ+Ô+ˆÝ˜˜x¨Ñ/Ô/ˆÝ/°vÐ>Ñ>Ô>ˆõ %Ñ&Ô&ð 0	kÕ,AÈÐ,OÑ,OÔ,O×,VÒ,VÑ,XÔ,Xð 0	kÕ\qÐy}Ð\~Ñ\~Ô\~÷  ]Fò  ]Fñ  ]Hô  ]Hð 0	kÝ˜4¨°TÐ:Ñ:Ô:Ð:Ý+¨HÑ5Ô5Ð5Ð5Ð5Ý‰ZŒZð -	kÕ2Ñ4Ô4×;Ò;Ñ=Ô=ð -	kÝ˜4Ñ Ô Ð Ý+¨HÑ5Ô5Ð5Ð5Ð5õ ˜Ô-Ñ.Ô.ˆDØñ 'kÝÐR°d·i²iÅÅCÈÁÄÑ6OÔ6OÐRÐRÐRÑSÔSÐSÝÐEÑFÔFÐFÝ 5Ñ 7Ô 7�Ø ð +Ý‘G”G�GÝÐ2Ñ3Ô3Ð3Ø -ð +ð +˜Ý˜k 4˜k˜kÑ*Ô*Ð*Ð*Ý‘”�Ý‘;”;ð 
DÝ˜.Ñ)Ô)Ð)ÝÐWÑXÔXÐXÐXÐXÝ‘X”Xð DÝ˜+Ñ&Ô&Ð&ÝÐeÑfÔfÐfÝÐXÑYÔYÐYÐYÐYåÐ4Ñ5Ô5Ð5ÝÐ4Ñ5Ô5Ð5ÝÐBÑCÔCÐCÐCÐCåÐ2Ñ3Ô3Ð3Ý 5Ñ 7Ô 7�Ø ð +Ý‘G”G�GÝÐ2Ñ3Ô3Ð3Ø -ð +ð +˜Ý˜k 4˜k˜kÑ*Ô*Ð*Ð*Ý‘”�Ý�kÑ"Ô"Ð"ÝÐEÑFÔFÐFÝ‘;”;ð kÝÐzÑ{Ô{Ð{Ð{Ð{Ý‘X”Xð kÝÐcÑdÔdÐdÝÐhÑiÔiÐiÐiÐiåÐOÑPÔPÐPÝÐiÑjÔjÐjÐjÐjà	Ð#Ò	#Ð	#õ ˜$ 	¨5Ñ1Ô1ˆÝ�d˜E 5Ñ)Ô)ˆÝ(Ñ*Ô*ð 	µ8±:´:ð 	ÝÐTÑUÔUÐUØˆFÝ"°3¨wÀÐHÑHÔHÐHÐHÐHð 
$Ð	#s�   Û[* Û*[<Û;[<Ü.\? Ü?]Ý]ß*_= ß=`à`áa áa$á#a$ä?e åe$å#e$æf' æ'f9æ8f9ìl$ ì$l6ì5l6í*m; í;nîn)Frå  )FrÃ   )FN)FNFr$   )r"   N)re  )TF)FFN)FFF)r©  rp  )r   FF)¨rU  rÇ  ri   r-  rp   rG   r  Údataclassesr   Úpathlibr   Ú__file__r'  rŸ   r  r°   r   Úgateway.restartr   r   r   Úhermes_cli.configr	   r
   r   r   r   r   r�  r   r   r   r   r   r   r   r   Úhermes_cli.colorsr   r   r   rE   r^   r3   rf   r%   rl   ru   Úfloatr   rB   rƒ   r«   r³   r2   rÂ   r0   rX  rÏ   râ   rò   rõ   rü   r  r  r  r  rû   rú   r÷   rù   r   r$  r#  r+  rF   rR   r¡   rJ  r*  rE  r    r¾   r»   r¿   rT  r]  rd  rg  r|  rv  r€  rƒ  ÚCompletedProcessr½   rÚ   rŒ  rŽ  r�  r1   r�  r’  rž  r   r§  rÀ  rÃ  rÇ  rÙ  rÜ  rß  rã  rè  ru  r÷  rù  rô   r  r  r  r  r  r8  r<  rB  rH  rK  rN  rQ  rº   r(  rç  rm  ro  rq  rt  r�  rS   r„  r�  r“  rš  rŸ  r¡  r§  r®  r¬  rµ  r»  rÉ  rv  r5  r{  rk  rq  rx  r|  r‡  r›  r�  r¡  r¾  rß  rä  rú  r  r
  r	  r   r*   r(   ú<module>r"     sì  ððð ð ð €€€Ø 	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ø 
€
€
€
Ø !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð àˆt�H‰~Œ~Ô$Ô+×3Ò3Ñ5Ô5€à (Ð (Ð (Ð (Ð (Ð (ðð ð ð ð ð ð ð ð ð ð
ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ,Ð +Ð +Ð +Ð +Ð +Ð +Ð +ð €�$ÐÑÔðTð Tð Tð Tð Tñ Tô Tñ ÔðTð<˜3ð <ð <ð <ð <ð~2˜ð 2  t¡ð 2ð 2ð 2ð 2ð2°Cð ¸Dð ð ð ð ð
 sð 
¨tð 
ð 
ð 
ð 
ð3 sð 3¸5ð 3ÀTð 3ð 3ð 3ð 3ðl˜T #œYð ¨S°4©Zð ÀsÈ3Äxð ÐTXð ð ð ð ñeð e S¨¤Xð e¸Tð eÈdÐSVÌið eð eð eð eñPð  C¨$¡Jð ÀTð ÐVZð ð ð ð ñ8>ð >¨4ð >¸EÀ$ÈÀ*Ô<Mð >ð >ð >ð >ð& ð#ñ%ð %Øð%à�c˜3�h”ð%ð 
ˆ#ˆsˆ(„^ð%ð %ð %ð %ðT Ø#Øð	,ð ,ð ,àð,ð ˜‘*ð,ð ð	,ð
 
ð,ð ,ð ,ð ,ñ^3ð 3¨Tð 3ÈÈtÉð 3Ð_cð 3ð 3ð 3ð 3ðl"¨ð "ð "ð "ð "ñ(ð (¨ð (Ð:Pð (ð (ð (ð (ðV TUð ð ð ˜u S¨# Xœ°°c´Ñ:ð ÀcÈDÁjð ÐY\ð ð ð ð ðJÐ.Dð JÈð Jð Jð Jð Jð LPØ05ñð  $ð ¸cÀD¹jð Ø)-ðØ:=ðð ð ð ð:#˜dð #ð #ð #ð #ðL,�$ð ,ð ,ð ,ð ,ð =Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ð <ð- $ð -ð -ð -ð -ñð  ð °$ð ð ð ð ð"¨ð ð ð ð ð	 4ð 	ð 	ð 	ð 	ð$�$ð $ð $ð $ð $ð#�Dð #ð #ð #ð #ð !€ØMÐ ð>˜ð >ð >ð >ð >ñ6ð ˜c D™jð °Cð ð ð ð ð8
'˜#ð 
'ð 
'ð 
'ð 
'ñLð L $ð L°4ð Lð Lð Lð Lðð ð ð ð  ,ñ ô ð ð ð ð ð ð ñMð Mð Mð Mñ,-ð -¨ð -¸ð -ð -ð -ð -ð" ;?ð Tð Tð T°4ð TÀ4ð Tð Tð Tð Tðn+¨cð +¸cð +ÈSð +ÐUYð +ð +ð +ð +ñ @ð @˜4ð @¨D°¬Ið @ð @ð @ð @ñBð B˜Dð B¨T°#¬Yð Bð Bð Bð Bð 7<ð ð ð ˜˜cœð ¨tð È*ÔJeð ð ð ð ñ*ð * ð *°#ð *ð *ð *ð *ð
 d¨3¤ið 
ð 
ð 
ð 
ð3 tð 3ð 3ð 3ð 3ð *=Ð �u˜S #˜X”Ð <Ð <Ñ <ð3Ð   c¨3 h¤ð ð ñ ð	 4¨¨d°D¨jÔ(9Ô#:ð 	ð 	ð 	ð 	ð# 4¨¨c°4¸¨oÔ(>Ô#?ð #ð #ð #ð #ðL- ð -ð -ð -ð -ñ
4ð 4ð 4ð 4ð( Øñ_ð _Øð_àð_ð ˆ3��T”
ˆ?Ôð_ð _ð _ð _ñD=ð =ð =ð =ð¨Sð °Tð ð ð ð ñ2ð 2¨#°©*ð 2ÀÀcÈ3ÐPSÀmÔ@Tð 2ð 2ð 2ð 2ð.¨Dð °S¸4±Zð ð ð ð ð c¨D¡jð ð ð ð ð
5¨C°$©Jð 
5ð 
5ð 
5ð 
5ñð ¨Dð ¸UÀ3ÈÁ:ÈtÐCSÔ=Tð ð ð ð ð>.; 5¨°©°cÐ)9Ô#:ð .;ð .;ð .;ð .;ñb5ð 5ð 5ð 5ð2˜Dð 2ð 2ð 2ð 2ðO ð Oð Oð Oð Oð˜$ ™+ð ð ð ð ðB	˜ð 	ð 	ð 	ð 	ð Q $ð Q°d¸3´ið QÀDÈÄIð Qð Qð Qð Qð˜sð °Sð ¸Sð ð ð ð ð4#°#ð #¸#ð #ð #ð #ð #ñ4hð h $ð h¸SÀ4¹Zð hÐSVð hð hð hð hðTJ¨ð J°ð Jð Jð Jð Jð°#ð ¸#ð ð ð ð ñ&_ð _ Dð _°Tð _ð _ð _ð _ñ
ð 
¨4ð 
¸Dð 
ð 
ð 
ð 
ñð ¨3ð ¸¸d¹
ð Èdð ð ð ð ñ(Dð (Dð (Dð (DñVlð l $ð l°4ð lð lð lð lð, Eð ,ð ,ð ,ð ,ñ7 ð 7 ˜4ð 7 °ð 7 ÈCÐRVÉJð 7 ð 7 ð 7 ð 7 ñtRð R˜dð Rð Rð Rð Rñ"Nð N˜$ð Nð Nð Nð NñNð N˜ð Nð Nð Nð Nñ9Pð 9P˜Dð 9Pð 9Pð 9Pð 9Pñz\,ð \,˜ð \,¨tð \,À4ð \,ð \,ð \,ð \,ðFL˜3ð Lð Lð Lð Lð ˜ð  ð  ð  ð  ðV ð Vð Vð Vð Vðps $ð sð sð sð sð¨ð ð ð ð ñ(?ð ?˜4ð ?ð ?ð ?ð ?ð6	%ð 	%ð 	%ð!ð !ð !ð2!ð !ð !ñ"'ð ' Eð '¸uÀt¹|ð 'ÐVZð 'ð 'ð 'ð 'ðT'ð 'ð 'ñ@$Gð $G˜ð $Gð $Gð $Gð $GñVð ˜ð ¨ð Àð ð ð ð ðL ØØØ)ð
ð 
ð 
ð *°[ÈdØFðHð Hà-Ð9]ÐkpØ!Ø<ð>ð >ð -ð  9Qð  _dØgðið ið
ðð ð, ØØØ(ð
ð 
ð 
ð )°KÈTØ9ð;ð ;à,Ð8iÐw|Ø!Ø<ð>ð >ð ,ð  8Pð  ^cØ[ð]ð ]ð
ð%ð ð: ØØØ&ð
ð 
ð 
ð" 'Ð2HÐVZØ=ð?ð ?à&Ð2HÐVZØCðEð Eà*Ð6ZÐhmØ!Ø>ð@ð @ð
ð+ð ð@ ØØØ*ð	
ð 	
ð 	
ð )Ð4fÐtyØWðYð Yà*Ð6pð  CØdðfð fà%Ð1hÐv{ØKðMð Mà+Ð7mð  |AØ!ØEðGð Gð (ð  4Ið  W\Øcðeð eð
ðð ð< ØØØ'ð	
ð 	
ð 	
ð &Ð1[ÐinØWðYð Yà'°;ÈDØ=ð?ð ?à/Ð;_ÐmrØ!ØAðCð Cð /ð  ;Sð  afØWðYð Yà,ð  9Oð  ]bØ]ð_ð _ð
ðð ð< ØØØ'ð	ð ð ØØØ&ð	ð ð ØØØ$ð
ð 
ð 
ð %°ÈUØRðTð Tà%Ð1SÐaeØRðTð Tà&°+È5ØYð[ð [á&±+È5ÙVðXð Xá*Ñ6_ÐmrØ!ÙJðLð Lð
ðð ñ6 ÙØÙ)ð
ñ 
ð 
ñ *Ñ5IÐW\Ù=ð?ð ?á(Ñ4GÐUYÙOðQð Qá*Ñ6mð  |AÙ@ðBð Bá(Ñ4kÐy~Ø!ÙPðRð Rñ (Ñ3yð  HMÙUðWð Wð
ðð ñ8 ÙØÙ)ð
ñ 
ð 
ñ *Ñ5IÐW\ÙMðOð Oá-Ñ9TÐbfÙPðRð Rð
ðð ñ& Ù ÙÙ$ð
ñ 
ð 
ñ %±ÀeÙDðFð Fá(±LÈdÙHðJð Já$Ñ0]ÐkpÙWðYð Yá-Ñ9xð  GLÙZð\ð \á+Ñ7eÐsxØ!ÙRðTð Tñ +Ñ6gÐuzÙGðIð Ið
ðð ñ< Ù,ØÙ#ð
ñ 
ð 
ñ $©xÀUÙ9ð;ð ;á#©xÀTÙ9ð;ð ;á*Ñ6dÐrwØ!ÙLðNð Nñ *Ñ5fÐtyÙGðIð Ið

ðð ñ2  Ù2ØÙ-ð
ñ 
ð 
ñ .¹ÐPUÙ5ð7ð 7á1¹]ÐX\ÙBðDð Dá.¹*ÐRWÙCðEð Eá+Ñ7GÐUYÙHðJð Já6ÑBTÐbfÙQðSð Sá*Ñ6\ÐjoÙ9ð;ð ;á3Ñ?mð  |AØ!ÙLðNð Nð
ðð ñ@ Ù"ØÙ(ð	ð ñ Ù)ØÙ-ð

ñ 

ð 

ñ .Ñ9qð  @EÙEðGð Gá+Ñ7TÐbfÙJðLð Lá0ñ  =\ð  joØ!Ùvðxð xñ 0ñ  <Ið  W\Ù]ð_ð _ð

ð!ð ñ: ÙÙÙ ð
ñ 
ð 
ñ !©OÈÙ8ð:ð :á'Ñ3FÐTXÙ<ð>ð >á'Ñ3xð  GLØ!ÙPðRð Rñ *Ñ5sð  BGÙKðMð Mð

ðð ði
k€
ñ\2˜tð 2¨ð 2ñ 2ð 2ð 2ðj ˜t Cœyð  ñ  ð  ð  ñF_2 tð _2ñ _2ð _2ð _2ñD'ð 'ð 'ñ-ð -ð -ñ+ð +ð +ñ8?ð 8?ð 8?ñvr,ð r,ð r,ðj˜tð ñ ð ð ð'(˜Tð '(ñ '(ð '(ð '(ñT|,ð |,ð |,ñ~i)ð i)ð i)ñXk5ð k5ð k5ñ\ohð ohð ohñdqð qð qñp
ð 
ð 
ñHIð HIð HIð HIð HIr*   