+
    jHàjpÁ  ã                   óz  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
Ht ^ RIHt ^ RIHt RtRRRR/R	 R
 lltR R ltR R ltRt]]P.                  ]3tR R lt]3R R lltR R ltR R ltR R ltR R ltR R lt R R lt!R  R! lt"R" R# lt#RSR$ R% llt$R& R' lt%RSR( R) llt&RTR* R+ llt'R,R-/R. R/ llt(R0 R1 lt)R2t*R3 R4 lt+R5 R6 lt, ! R7 R84      t-RUR9 R: llt.R; t/R< R= lt0R> R? lt1RVR@ RA llt2RB RC lt3RD RE lt4RF RG lt5RH t6RSRI RJ llt7RK RL lt8RM RN lt9RO RP lt:RQ RR lt;R# )Wan  Dashboard/serve support: managed-service restart (systemd/respawn), status/listening probes, SSH session token file, named-profile routing, web-dist resolution, update stdio hangup protection.

Split out of ``hermes_cli/main.py``. Names that still live in main (``PROJECT_ROOT``, ...)
are imported lazily inside the functions that use them (avoids an import cycle).
N)ÚPath)ÚNoReturn)Ú
line_input)Úis_desktop_owned_backendzG  Pre-build first:  npm install --workspace web && npm run build -w webÚexclude_pidsÚ
scope_homec                ó„   € V ^8„  d   QhR\         \        ,          R,          R\        R,          R\        \        ,          /# )é   r   Nr   Úreturn)ÚsetÚintÚstrÚlist)Úformats   "Ú>/home/ubuntu/.hermes/hermes-agent/hermes_cli/main_dashboard.pyÚ__annotate__r      s8   € ÷ Pñ P´´Cµ¸4µð PÜ+.°­:ðPÜAEÄcÅñPó    c                óÚ   € ^ RI HpHpHpHp V! V R7       UUu. uF  w  rgVNK	  	  pppV! 4       p	V Uu. uF  qc! Wi4      '       d   K  VNK  	  ppV'       d	   V! W�4      # T# u uppi u upi )au  PIDs of running ``dashboard``/``serve`` backends the caller may stop.

*scope_home*: keep only backends whose resolved Hermes home (see
``_hermes_home_for_pid``) is this home; unreadable ownership is spared, never guessed.
``--stop`` and the post-update cleanup pass their own home so another install's or
profile's backend on the same machine is never a target (#113978).
)Ú_caller_ancestor_pidsÚ_is_caller_wrapper_shellÚ_pids_owned_by_hermes_homeÚ_scan_dashboard_processes)r   )Úhermes_cli.dashboard_procsr   r   r   r   )
r   r   r   r   r   r   ÚpidÚ_cmdÚpidsÚ	ancestorss
   $$        r   Ú_find_stale_dashboard_pidsr      sr   € ÷ó ñ ";ÈÕ!UÔVÑ!U‘I�C‹CÑ!U€DÑVñ &Ó'€IÙÓP™4�CÐ'?À×'O�CˆC™4€DÐPß;EÑ% dÓ7ÐOÈ4ÐOùó Wùò Qs   ™A"´A(ÁA(c                ój   € V ^8„  d   QhR\         R\        \         \         \        3,          R,          /# )r	   Úcommandr
   N)r   Útupler   )r   s   "r   r   r   .   s*   € ÷ ñ ¤cð ¬e´C¼¼c°MÕ.BÀTÕ.Iñ r   c                ój  € ^ RI Hp V! V 4      pVR9  d   R# RpRp\        P                  ! RV 4      pV'       d    \	        VP                  ^4      4      p\        P                  ! RV 4      pV'       d+   VP                  ^4      P                  R4      ;'       g    RpW$V3#   \         d     R# i ; i)	zñBest-effort parse of a dashboard/server cmdline into mode, host, and port.

The mode is the canonical holder subcommand, never an argv substring: this gates the launchd
backend inventory (a kill + kickstart path) and ``--status`` (#121156).
)Ú_hermes_holder_subcommandNiŸ#  ú	127.0.0.1z(?:^|\s)--port(?:=|\s+)(\d+)z/(?:^|\s)--host(?:=|\s+)(\"[^\"]+\"|'[^']+'|\S+)z"')Ú	dashboardÚserve)Úhermes_cli.update_cmd_windowsr"   ÚreÚsearchr   ÚgroupÚ
ValueErrorÚstrip)r   r"   ÚmodeÚportÚhostÚ
port_matchÚ
host_matchs   &      r   Ú_parse_dashboard_runtimer1   .   s®   € õ HÙ$ WÓ-€DØÐ)Ô)Ùà€DØ€Dä—’Ð:¸GÓD€Jßð	Ü�z×'Ñ'¨Ó*Ó+ˆDô —’ÐMÈwÓW€JßØ×Ñ Ó"×(Ñ(¨Ó/×>Ð>°;ˆà�tÐÐøô ô 	Úð	ús   ¼B# Â#B2Â1B2c                ó>   € V ^8„  d   QhR\         R,          R\         /# )r	   r.   Nr
   ©r   )r   s   "r   r   r   J   s   € ÷ ñ ¤ d¥
ð ¬sñ r   c                ój   € T ;'       g    RP                  4       P                  R4      pVR9   d   R# V# )zDMap wildcard binds to a loopback address suitable for local probing.r#   z[]>   Ú ú::ú0.0.0.0)r+   )r.   Ú
normalizeds   & r   Ú_dashboard_probe_hostr9   J   s5   € à×%Ð%˜+×,Ñ,Ó.×4Ñ4°TÓ:€JØÐ*Ô*ÙØÐr   zhermes-dashboard.servicec                óf   € V ^8„  d   QhR\         \        ,          R\        R\        P                  /# )r	   ÚcmdÚtimeoutr
   )r   r   r   Ú
subprocessÚCompletedProcess)r   s   "r   r   r   W   s0   € ÷ oñ o”Dœ•Ið o¬3ð o´:×3NÑ3Nñ or   c          
     ó<   € \         P                  ! V RRRRVRR7      # )zQCaptured, text-decoded ``subprocess.run`` for short local probes (systemctl, ps).Túutf-8ÚreplaceF)Úcapture_outputÚtextÚencodingÚerrorsr<   Úcheck)r=   Úrun)r;   r<   s   &$r   Ú
_run_proberH   W   s&   € ä�>Š>Ø˜D t°gÀiÐY`Ðhmôoð or   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r	   ÚreasonÚunitr
   ©r   Úbool)r   s   "r   r   r   ]   s'   € ÷ Lñ L¬sð L¼#ð LÔ\`ñ Lr   c                ó¬  a€ \         P                  R8X  d   R# R^
/R R llpRpR! F�  p V! . VORNSNRNR	N5!  pTP                  ^ 8w  d   K(  TP                  ;'       g    R
P                  4       p\        ;QJ d    T3R lT 4       F  '       g   K   RM	  RM! T3R lT 4       4      '       g   KŽ  Tp M	  Vf   R#  V! . VORNSN5!  pV! . VORNSN5!  pTP                  ;'       g    R
P                  4       p	TP                  ;'       g    R
P                  4       p
T	R8w  d
   T
R"9  d   R# \        RT  R24       T'       d   RMRpR.TORNSN5.pT'       g   TP                  RRRRS34       . pT F—  p \        \        T4      ^<R7      pTP                  ^ 8X  d   \        RS 24        R# TP                  RP                  T4       RTP                  ;'       g    TP                  ;'       g    R
P                  4        24       K™  	  \        RS 24       T F)  pTP                  4       '       g   K  \        RT 24       K+  	  \        R4       \        RT R S 24       R#   \         d     EKZ  i ; i  \         d     R# i ; i  \         d2   pTP                  RP                  T4       RT 24        Rp?EKR  Rp?ii ; i)#u)  Restart a systemd-managed dashboard instead of raw-killing its PID.

True when a unit was found and handled (success or printed failure) â€” which
deliberately stops the caller's ``os.kill`` fallback: systemd treats a direct
SIGTERM as a clean stop, so ``Restart=on-failure`` won't bring it back.
Úwin32Fr<   c                óP   € V ^8„  d   QhR\         R\        R\        P                  /# )r	   Úargsr<   r
   )r   r   r=   r>   )r   s   "r   r   Ú8_restart_managed_dashboard_service.<locals>.__annotate__g   s,   € ÷ Añ Aœ#ð A¬ð A´Z×5PÑ5Pñ Ar   c                 ó"   € \        R .VOV R7      # )Ú	systemctl©r<   )rH   )r<   rQ   s   $*r   Ú
_systemctlÚ6_restart_managed_dashboard_service.<locals>._systemctlg   s   € Ü˜;Ð.¨Ð.¸Ô@Ð@r   Nzlist-unit-filesz--no-legendz
--no-pagerr5   c              3   óˆ   <"  € T F7  qP                  4       '       g   K  VP                  4       R ,          S.8H  x € K9  	  R# 5i):é    é   NN)Úsplit)Ú.0ÚrowrK   s   & €r   Ú	<genexpr>Ú5_restart_managed_dashboard_service.<locals>.<genexpr>w   s,   øé € ÐN±Y¨cÇ)Á)Ç+Ô)ˆs�y‰y‹{˜3Õ D 6Ö)³Yùs
   ƒAŸ#ATz	is-activez
is-enabledÚactiveu+   
âŸ² Restarting managed dashboard service (Ú)zsystemctl --userzsudo systemctlrT   ÚrestartÚsudoz-nrU   Ú z: u       âœ“ restarted u       âœ— failed to restart z      zl  Dashboard is managed by systemd; not raw-killing its PID because systemd would treat that as a clean stop.z  Restart manually: z	 restart ))ú--user© >   ÚlinkedÚstaticÚenabledÚ	generatedúlinked-runtimeúenabled-runtime)ÚsysÚplatformÚ_SYSTEMCTL_ERRORSÚ
returncodeÚstdoutÚ
splitlinesÚanyr+   ÚprintÚappendrH   r   ÚjoinÚstderr)rJ   rK   rV   ÚscopeÚ	candidateÚresultÚ	unit_rowsr`   ri   Úactive_stateÚenabled_stateÚscope_labelÚcommandsrE   r   ÚeÚerrs   &f               r   Ú"_restart_managed_dashboard_servicer‚   ]   s×  ø€ ô ‡|�|�wÔÙðA¨b÷ Að %)€EÛ&ˆ	ð	ÙÐa ÐaÐ,=Ða¸tÐaÀ]ÐaÐT`ÓaˆFð ×Ñ Ô!ÙØ—]‘]×(Ð( b×4Ñ4Ó6ˆ	ß‹3ÔN±YÓN�3�3Š3ÔN±YÓN×NÔNØˆEÙñ 'ð ‚}ÙðÙÐ6˜UÐ6 KÐ6°Ó6ˆÙÐ8˜eÐ8 \Ð8°4Ó8ˆð —M‘M×'Ð' R×.Ñ.Ó0€LØ—^‘^×)Ð) r×0Ñ0Ó2€MØ�xÔ Mð :ô %ñ ä	Ð8¸¸ÀÐ
BÔCç(-Ñ$Ð3C€KØÐ6˜uÐ6 iÐ6°Ñ6Ð7€Hßð 	�‰˜  {°I¸tÐDÔEà€FÛˆð	Ü¤ W£°rÔ:ˆFð ×Ñ Ô!ÜÐ& t fÐ-Ô.ÚØ�‰˜Ÿ™ 'Ó*Ð+¨2¨v¯}©}×/SÐ/SÀÇÁ×/SÐ/SÐQS×.ZÑ.ZÓ.\Ð-]Ð^Ö_ñ ô 
Ð& t fÐ
-Ô.ÛˆØ�9‰9�;Œ;Ü�F˜3˜%�.Ö!ñ ô 
ð	4ôô 
Ð   ¨Y°t°fÐ
=Ô>Ùøôo !ô 	Ûð	ûô ô Úðûô. !ô 	Ø�M‰M˜SŸX™X gÓ.Ð/¨r°!°Ð5Ô6Þûð	ús;   «I2ÃJ Æ JÉ2JÊJÊJÊJÊKÊ"%KËKc                ó$   € V ^8„  d   QhR\         /# )r	   r   ©r   )r   s   "r   r   r   ¬   s   € ÷ ñ ¤Sñ r   c              #  ó\  "  €  \        RV  R24      pVP                  4       '       g   R# VP                  RRR7      pTP                  4        F@  pTP                  4       P                  R^4      p\        T4      ^8X  g   K5  T^,          x € KB  	  R#   \        \        3 d     R# i ; i5i)zZYield the ``0::<path>`` cgroup paths from ``/proc/<pid>/cgroup``; nothing when unreadable.ú/proc/z/cgroupNú	utf-8-sigrA   )rD   rE   r6   )	r   Úis_fileÚ	read_textÚOSErrorÚPermissionErrorrr   r+   r[   Úlen)r   Úcgroup_pathrC   ÚlineÚpartss   &    r   Ú_pid_unified_cgroup_entriesr�   ¬   s›   é € ðÜ˜V C 5¨Ð0Ó1ˆØ×"Ñ"×$Ò$ÙØ×$Ñ$¨kÀ)Ð$ÓLˆð —‘Ö!ˆØ—
‘
“×"Ñ" 4¨Ó+ˆÜˆu‹:˜Ž?Ø˜•(ŒNó "øô ”_Ð%ô Úðüs8   ‚B,„%B ©B,«B ¾A B,ÂB,ÂB)Â%B,Â(B)Â)B,c                ó>   € V ^8„  d   QhR\         R\        R,          /# ©r	   r   r
   N©r   r   )r   s   "r   r   r   »   s   € ÷ ñ ¤cð ¬c°D­jñ r   c                óÎ   € \        V 4       FU  pVP                  R4      '       g   K  VP                  R^4      R,          pV'       g   K?  \        W!V 4      '       g   KS  Vu # 	  R# )ak  The systemd service unit that supervises *pid* (``hermes-serve.service``), or None.

A ``.service`` cgroup alone only says where the process was started: a dashboard launched by
hand from a shell that itself runs under some unit (a CI runner agent, ``cron.service``, a
tmux or IDE user service, the gateway's own terminal tool) sits in THAT unit's cgroup. The
unit owns the backend only when its live ``MainPID`` is this PID; otherwise restarting it
restarts an unrelated service and leaves the dashboard down. None when the PID isn't part of
a service, ownership can't be proved, the file is unreadable, or off Linux.
z.serviceÚ/Néÿÿÿÿ)r�   ÚendswithÚrsplitÚ_unit_main_pid_is)r   Úcg_pathÚsvc_names   &  r   Ú_get_systemd_service_for_pidrœ   »   sU   € ô /¨sÖ3ˆØ×Ñ˜J×'Ô'Ø—~‘~ c¨1Ó-¨bÕ1ˆHß‰xÔ-¨hÀ×EÔEØ’ñ	 4ñ
 r   c                óH   € V ^8„  d   QhR\         R\         R\        R\        /# )r	   r›   r�   r   r
   ©r   r   rM   )r   s   "r   r   r   Í   s(   € ÷ ñ ¤ð ´#ð ¼Cð ÄDñ r   c                ó`  € \        V4      pRR..R. ./P                  T;'       g    R. R..4      pV Fd  p \        R.VORNV NRNRN^
R	7      pTP                  ^ 8X  g   K/  TP
                  ;'       g    RP                  4       \        T4      8X  g   Kc   R
# 	  R#   \         d     Kx  i ; i)zPTrue when *svc_name*'s live ``MainPID`` is *pid* (read-only ``systemctl show``).Úuserre   Úsystemr5   rT   Úshowz--property=MainPIDz--valuerU   TF)Ú_extract_scope_from_cgroupÚgetrH   ro   rp   rq   r+   r   )r›   r�   r   rx   ÚscopesÚ
scope_argsrz   s   &&&    r   r™   r™   Í   sÄ   € ä& {Ó3€EØ˜�z�l H¨r¨dÐ3×7Ñ7¸¿¸ÀÀbÈ8È*ÐEUÓV€FÛˆ
ð	ÜØÐ]˜zÐ]¨6Ð]°8Ð]Ð=QÐ]ÐS\Ð]ÐgiôkˆFð ×Ñ Ö! v§}¡}×':Ð':¸×&AÑ&AÓ&CÄsÈ3ÃxÖ&OÚñ ñ øô	 !ô 	Úð	ús   ¸BÂB-Â,B-c                ó>   € V ^8„  d   QhR\         R\         R,          /# )r	   Úcgroup_entryr
   Nr3   )r   s   "r   r   r   Ü   s   € ÷ ñ ¬Sð ´S¸4µZñ r   c                ó*   € RV 9   d   R# RV 9   d   R# R# )uc   ``user`` / ``system`` from a cgroup path (``/user.slice/â€¦`` vs ``/system.slice/â€¦``), else None.z/system.slice/r¡   z/user.slice/r    Nrf   )r¨   s   &r   r£   r£   Ü   s   € à˜<Ô'ÙØ˜Ô%ÙÙr   c                ó>   € V ^8„  d   QhR\         R\        R,          /# r’   r“   )r   s   "r   r   r   å   s   € ÷ 8ñ 8œcð 8¤c¨D¥jñ 8r   c                ó,   € \        \        V 4      R4      # )zGThe unified (``0::``) cgroup path from ``/proc/<pid>/cgroup``, or None.N)Únextr�   )r   s   &r   Ú_get_pid_cgroup_pathr­   å   s   € äÔ+¨CÓ0°$Ó7Ð7r   c                ón   € V ^8„  d   QhR\         R\        \        \        R,          3,          R,          /# r’   )r   r    r   )r   s   "r   r   r   ê   s0   € ÷ Mñ M¤ð M¬¬c´3¸µ:¨oÕ(>ÀÕ(Eñ Mr   c                ód   € \        V 4      pVf   R# T\        \        V 4      ;'       g    R4      3# )zå``(unit, scope)`` of the systemd unit whose live ``MainPID`` is *pid*; ``None`` when no unit
provably owns it (see :func:`_get_systemd_service_for_pid`). Scope is ``user``/``system`` or
``None`` when the cgroup path does not say.Nr5   )rœ   r£   r­   )r   rK   s   & r   Ú_systemd_owner_for_pidr°   ê   s5   € ô (¨Ó,€DØ‚|ÙØÔ+Ô,@ÀÓ,E×,KÐ,KÈÓLÐLÐLr   c                ó`   € V ^8„  d   QhR\         R\         R,          R\        \         ,          /# )r	   rK   rx   Nr
   )r   r   )r   s   "r   r   r   ô   s.   € ÷ añ a¤Cð a´°dµ
ð a¼tÄC½yñ ar   c                óZ   € RV  2RV  2r2RV.RV./P                  T;'       g    RW#.4      # )zVThe command(s) that restart *unit* in its scope; both forms when the scope is unknown.zsystemctl --user restart zsudo systemctl restart r    r¡   r5   )r¤   )rK   rx   Úuser_cmdÚ
system_cmds   &&  r   Ú_systemd_restart_commandsrµ   ô   sC   € à6°t°fÐ=ÐAXÐY]ÐX^Ð?_ˆjØ�X�J ¨:¨,Ð7×;Ñ;¸E¿K¸KÀRÈ(ÐI_Ó`Ð`r   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# ©r	   r   r
   ©r   r   )r   s   "r   r   r   ú   s   € ÷ 3ñ 3¤t¬C¥yð 3´Sñ 3r   c                ó2   € RP                  R V  4       4      # )zRJoin restart commands as a user-facing hint: each backticked, separated by " or ".z or c              3   ó.   "  € T F  pR V R 2x € K  	  R# 5i)Ú`Nrf   )r\   Úcs   & r   r^   Ú+_format_restart_commands.<locals>.<genexpr>ü   s   é € Ð2© A˜˜1˜#˜Q•x«ùs   ‚)rv   )r   s   &r   Ú_format_restart_commandsr¾   ú   s   € à�;‰;Ñ2©Ó2Ó2Ð2r   c                óJ   € V ^8„  d   QhR\         R\         R,          R\        /# )r	   r›   r�   Nr
   rL   )r   s   "r   r   r   ÿ   s&   € ÷ ñ ¬3ð ¼SÀ4½Zð ÔSWñ r   c                óî   € V'       d   \        V4      MRpRRV .pRRRV .pRV.RV./P                  W#V.4      pV F#  p \        V^R7      P                  ^ 8X  d    R# K%  	  R	#   \         d     K7  i ; i)
zƒRestart *svc_name* via systemctl (``--user`` for user-scope units). True on success.

Unknown scope tries system first, then user.
NrT   rb   re   r    r¡   rU   TF)r£   r¤   rH   rp   ro   )r›   r�   rx   r´   r³   Ú
candidatesr;   s   &&     r   Ú_try_restart_systemd_servicerÂ   ÿ   s–   € ÷
 8CÔ& {Ô3È€EØ˜y¨(Ð3€JØ˜X y°(Ð;€HØ˜8˜* h°°Ð=×AÑAÀ%ÐV^ÐI_Ó`€JÛˆð	Ü˜# rÔ*×5Ñ5¸Ô:Úñ ;ñ ñ øô !ô 	Úð	ús   Á A%Á%A4Á3A4c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# ©r	   r
   )r   r    r   r   )r   s   "r   r   r     s!   € ÷ ñ œT¤%¬¬T¨	Õ"2Õ3ñ r   c                  ó~   € R \         P                  ! 4       R,          R,          3R \        R4      3R\        R4      3.# )ÚagentÚLibraryÚLaunchAgentsz/Library/LaunchAgentsÚdaemonz/Library/LaunchDaemons)r   Úhomerf   r   r   Ú_launchd_plist_dirsrË     s@   € à	”$—)’)“+ 	Õ)¨NÕ:Ð;Ø	”$Ð.Ó/Ð0Ø	”4Ð0Ó1Ð2ðð r   c          
      óæ   € V ^8„  d   QhR\         \        \        \        3,          ,          R,          R\         \        \        \        \         \        ,          \        R,          3,          ,          /# )r	   Ú
plist_dirsNr
   )r   r    r   r   r   )r   s   "r   r   r     sJ   € ÷ 1ñ 1Ü”Uœ3¤˜9Õ%Õ&¨Õ-ð1ä	Œ%””Sœ$œs�)¤S¨4¥ZÐ/Õ
0Õ1ñ1r   c           	     ó@  € \         P                  R8w  d   . # ^ RIp^ RIHp ^ RIHp \        P                  ! 4       p. pV e   T M	\        4        EFd  w  rg \        VP                  R4      4      pT EF<  p	 \        T	R4      ;_uu_ 4       p
TP                  T
4      pRRR4       \#        X\$        4      '       g   KK  \'        TP)                  R4      ;'       g    R4      P+                  4       pTP)                  R	4      pT'       d   \#        T\,        4      '       d	   T'       g   K¶  T Uu. uF  p\'        T4      NK  	  pp\/        \0        P2                  ! T4      4      f   Kó  TR
8X  d   RM	RT 2RT 23pT F0  p T! TT4      w  ppT'       g   K  TP7                  TYÏT34        EK:  	  EK?  	  EKg  	  V#   \         d     EKz  i ; i  + '       g   i     EL9; i  \        \        TP                   T3 d     EK�  i ; iu upi   \4         d    RRpp L’i ; i)u—  ``(domain, label, program_arguments, live_pid)`` for every LOADED launchd job whose
``ProgramArguments`` is a ``hermes dashboard`` / ``hermes serve`` backend. macOS only (empty
elsewhere). Reads the plists (unreadable/malformed ones are skipped) and asks ``launchctl print``
per candidate label â€” a job that is not loaded in any domain is not returned, so an operator's
stale plist never claims a process.ÚdarwinN)Ú
ExpatError)Ú_launchd_print_service_pidz*.plistÚrbÚLabelr5   ÚProgramArgumentsrÉ   zgui/zuser/F)r¡   )rm   rn   ÚplistlibÚxml.parsers.expatrÐ   Úhermes_cli.gatewayrÑ   ÚosÚgetuidrË   ÚsortedÚglobrŠ   ÚopenÚloadr*   ÚInvalidFileExceptionÚ
isinstanceÚdictr   r¤   r+   r   r1   Úshlexrv   ro   ru   )rÍ   rÕ   rÐ   rÑ   ÚuidÚjobsÚkindÚ	plist_dirÚplistsÚ
plist_pathÚfÚdataÚlabelrQ   ÚaÚargvÚdomainsÚdomainÚloadedÚlive_pids   &                   r   Ú_loaded_launchd_backend_jobsrñ     sä  € ô ‡|�|�xÔØˆ	ÛÝ,å=Ü
�)Š)‹+€CØ9;€DØ*4Ò*@™JÔFYÓF[Ó[‰ˆð	Ü˜IŸN™N¨9Ó5Ó6ˆFô !ˆJðÜ˜* d×+Ô+¨qØ#Ÿ=™=¨Ó+�D÷ ,ô ˜d¤D×)Ò)ÙÜ˜Ÿ™ Ó)×/Ð/¨RÓ0×6Ñ6Ó8ˆEØ—8‘8Ð.Ó/ˆDß¤
¨4´× 6Ò 6¿dÙÙ$(Ó)¡D˜q”C˜–F¡DˆDÐ)Ü'¬¯
ª
°4Ó(8Ó9ÒAÙØ%)¨XÔ%5‘k¸dÀ3À%¸LÈEÐRUÐQVÈ-Ð;XˆGÛ!�ð3Ù'AÀ&È%Ó'PÑ$�F˜H÷ ‘6Ø—K‘K ¨°hÐ ?Ô@Ûô "ô) !ñ \ðB €Køô= ô 	Ûð	ú÷ ,×+Ð+ûô œZ¨×)FÑ)FÈ
ÐSô Ûðüò *øô )ô 3Ø',¨d˜H�F™Hð3úsZ   ÁF:Á7G!ÂG	ÂG!Ä,HÅ>HÆ:G
Ç	G
ÇGÇG!ÇG!Ç!HÈHÈH	ÈH	c                óv  € V ^8„  d   QhR\         R\        \        ,          R,          R\        \        \        \        \        \        ,          \         R,          3,          ,          R\        \         ,          \        \         R3,          ,          R\        \        \        \         R,          3,          R,          /# )r	   r   ÚcmdlineNrã   r   .r
   )r   r   r   r    )r   s   "r   r   r   Q  s�   € ÷ ñ Ü	ðÜœC•y 4Õ'ðÜ/3´E¼#¼sÄDÌÅIÌsÐUYÍzÐ:YÕ4ZÕ/[ðä”C�yœ5¤ c �?Õ*ðô Œ3””S˜4•ZÐÕ  4Õ'ñr   c                ó¦   € R R lpV FD  w  rVrxVe   W€8X  g   Wƒ9   d   WVV3u # Vf   K"  V! \        V4      4      V! V4      8X  g   K@  WVV3u # 	  R# )uU  ``(domain, label, live_pid)`` of the loaded launchd job that owns *pid*: launchd reports *pid*
(or one of its *ancestors* â€” a plist may wrap the backend in ``/bin/sh -c â€¦`` without ``exec``)
as the job's live process, OR the process runs the job's ``ProgramArguments`` â€” a detached copy
of a supervised backend (an earlier respawn) holds the port the job needs, and respawning it again
would only re-create that conflict. ``--no-open`` is ignored on both sides: the respawn path adds
it, so an earlier respawn's argv is the plist's plus that flag. None when no loaded job claims
the process.c                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# ©r	   rì   r
   r¸   )r   s   "r   r   Ú1_launchd_job_owning_backend.<locals>.__annotate__\  s"   € ÷ 5ñ 5”Dœ•Ið 5¤$¤s¥)ñ 5r   c                 ó@   € V  Uu. uF  qR 8w  g   K  VNK  	  up# u upi )ú	--no-openrf   )rì   rë   s   & r   Ú_normÚ*_launchd_job_owning_backend.<locals>._norm\  s!   € ÙÓ4™4�a¨Ñ#3—�™4Ñ4Ð4ùÒ4s   …’N)r   )	r   ró   rã   r   rú   rî   rê   rì   rð   s	   &&&&     r   Ú_launchd_job_owning_backendrü   Q  s\   € õ5ó *.Ñ%ˆ�tØÒ X¤_¸Ô8MØ 8Ð,Ò,ØÔ¡5¬¨g«Ó#7¹5À»;Ö#FØ 8Ð,Ò,ñ	 *.ñ
 r   r<   g      .@c          
      ób   € V ^8„  d   QhR\         R\         R\        R,          R\        R\        /# )r	   rî   rê   Úold_pidNr<   r
   )r   r   ÚfloatrM   )r   s   "r   r   r   g  s5   € ÷ ñ ¤ð ¬Sð ¼3À½:ð ÔSXð Ôdhñ r   c               ó”   € ^ RI Hp  \        RRV  RV 2.^R7      P                  ^ 8w  d   R# V! WW0R7      #   \         d     R# i ; i)uÍ  Bring a launchd-supervised backend back after its process was stopped: ``launchctl kickstart
<domain>/<label>`` (no ``-k`` â€” a KeepAlive job may already have respawned it, and a kill would
take that fresh process down), then require launchd to report a live PID other than *old_pid*
within *timeout*. A kickstart that returns 0 only means "restart requested"; a job that is loaded
but never comes back on a fresh PID is a failure the operator must hear about.)Ú_wait_for_launchd_service_pidÚ	launchctlÚ	kickstartr•   rU   F)rþ   r<   rî   )r×   r  rH   rp   ro   )rî   rê   rþ   r<   r  s   &&&$ r   Ú_restart_launchd_jobr  g  sW   € õ AðÜ�{ K°F°8¸1¸U¸GÐ1DÐEÈrÔR×]Ñ]ÐabÔbÙÙ,¨UÈWÔdÐdøÜô Úðús   ˆ$8 ®	8 ¸AÁAc                óT   € V ^8„  d   QhR\         R\        \        ,          R,          /# r’   )r   r   r   )r   s   "r   r   r   v  s#   € ÷ ñ ¤Cð ¬D´­I¸Õ,<ñ r   c                ó,  € \         P                  R8X  d   R#  RV  R2p\        P                  P	                  V4      '       dt   \        VR4      ;_uu_ 4       pVP                  4       pRRR4       XP                  R4       Uu. uF  qD'       g   K  VP                  RRR	7      NK!  	  ppT;'       g    R# \        R
R\        V 4      RR.^
R7      pVP                  ^ 8w  d   R# VP                  ;'       g    RP                  4       pV'       g   R#  \        P                  ! V4      pT;'       g    R#   + '       g   i     LÕ; iu upi   \         d    TP                  4       p LAi ; i  \         \        \"        P$                  3 d     R# i ; i)z±Exact argv of a running process: ``/proc/<pid>/cmdline`` (Linux), ``ps -o command=`` + shlex
(macOS), None on Windows (no graceful taskkill window; Desktop manages its backend).rO   Nr†   z/cmdlinerÒ   ó    r@   rA   )rE   Úpsú-pz-ozcommand=rU   r5   )rm   rn   rØ   ÚpathÚexistsrÜ   Úreadr[   ÚdecoderH   r   rp   rq   r+   rá   r*   rŠ   r=   ÚTimeoutExpired)r   Úcmdline_pathrè   ÚrawÚpartrì   rz   r   s   &       r   Ú_dashboard_cmdline_for_pidr  v  sK  € ô ‡|�|�wÔÙðØ ˜u HÐ-ˆÜ�7‰7�>‰>˜,×'Ò'Ü�l D×)Ô)¨QØ—f‘f“h�÷ *àGJÇyÁyÐQXÔGYÓbÑGY¸tÓ]aÔ:�D—K‘K °	�KÖ:ÑGYˆDÐbØ—<�<˜4ÐÜ˜T 4¬¨S«°4¸ÐDÈbÔQˆØ×Ñ Ô!ÙØ—=‘=×&Ð& B×-Ñ-Ó/ˆßÙð	#Ü—;’;˜wÓ'ˆDð �|ˆ|�tÐ÷ *×)üâbøô ô 	#Ø—=‘=“?ŠDð	#ûô ”Z¤×!:Ñ!:Ð;ô Úðúsƒ   ™*E/ ÁE/ ÁD6Á)E/ Â	E	ÂE	Â)
E/ Â4E/ Â7,E/ Ã%E/ Ã8E/ ÄE Ä*E/ Ä3E/ Ä6E	ÅE/ ÅE,Å)E/ Å+E,Å,E/ Å/ FÆFg      ð?c                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# rö   r¸   )r   s   "r   r   r   ”  s"   € ÷ ñ ´4¼µ9ð ÄÄcÅñ r   c                óÆ  € \        \        4      P                  4       P                  ^,          p\	        V 4      ^8”  dš   \
        P                  P                  V ^ ,          4      P                  R4      '       d_   \
        P                  P                  V ^,          4      R8X  d4   \        V ^,          4      VR,          8w  d   ^ RI	H
p V! WR,          4      # \        V 4      # )a/  Rebuild a captured ``[<interpreter>, <hermes launcher>, ...]`` argv on this install's launcher.

A pre-PM-takeover install left ``~/.local/bin/hermes`` as a symlink to a Python console
script, so the kernel recorded a manual backend as ``[<old venv python>, <launcher>, dashboard,
...]``. The takeover then rewrote that launcher into a POSIX shell shim, and replaying the
captured argv verbatim asks the old interpreter to parse a shell script (#124778). This
checkout's own ``hermes`` entry script stays Python, so it and every other shape replay unchanged.
ÚpythonÚhermes)Úruntime_commandºr	   NN)r   Ú__file__ÚresolveÚparentsrŒ   rØ   r
  ÚbasenameÚ
startswithÚhermes_cli._launchersr  r   )rì   Úrootr  s   &  r   Ú(_respawnable_command_for_current_installr   ”  sš   € ô ”‹>×!Ñ!Ó#×+Ñ+¨AÕ.€DÜˆD‹	�AŒœ"Ÿ'™'×*Ñ*¨4°­7Ó3×>Ñ>¸x×HÒHÜ—‘× Ñ   a¥Ó)¨XÔ5¼$¸tÀA½w»-È4ÐRZÍ?Ô:ZÝ9Ù˜t¨"¥XÓ.Ð.Ü�‹:Ðr   c                óˆ   € V ^8„  d   QhR\         \         \        ,          ,          R\         \         \        ,          ,          /# r·   r¸   )r   s   "r   r   r   ¥  s*   € ÷ 03ñ 03¬4´´Sµ	­?ð 03¼tÄDÌÅI½ñ 03r   c                ó¨  € ^ RI Hp . p. p. pV! 4       R,          R,          p\        P                  ! \        4      ;_uu_ 4        VP
                  P                  RRR7       RRR4       V  F‹  p\        V4      pRV9   d   RV9  d   . VORNp \        VR	4      ;_uu_ 4       p\        P                  ! V\        P                  V\        P                  RRR
7      p	RRR4       VP                  WgX	34       K�  	  V'       d   \         P"                  ! \$        4       V FT  w  rgp	V	P'                  4       f   VP                  V4       K+  VP                  WgR\$        R RV	P(                   R234       KV  	  V F%  p\+        R\,        P.                  ! V4       24       K'  	  V F+  w  r·p\+        R\,        P.                  ! V4       RV 24       K-  	  V UUu. uF  w  p q¶NK
  	  upp#   + '       g   i     EL‘; i  + '       g   i     EL+; i  \        \        3 d)   p
TP                  Yg\        T
4      34        Rp
?
EKÚ  Rp
?
ii ; iu uppi )a  Respawn manually-started dashboards after ``hermes update``, detached, logging to
``logs/dashboard-restart.log``; returns the argvs that failed to spawn. Callers pre-filter via
``_filter_dashboard_respawn_candidates`` (no Desktop ``--port 0`` backends, capped per profile).

See #78821.
)Úget_hermes_homeÚlogszdashboard-restart.logT©r  Úexist_okNr$   rù   Úab)Ústdinrq   rw   Ústart_new_sessionÚ	close_fdszchild exited during the first z.0fzs (code ra   u       âœ“ restarted: u       âœ— failed to restart (z): )Úhermes_constantsr#  Ú
contextlibÚsuppressrŠ   ÚparentÚmkdirr   rÜ   r=   ÚPopenÚDEVNULLÚSTDOUTru   r*   r   ÚtimeÚsleepÚ_RESPAWN_LIVENESS_GRACE_SECONDSÚpollrp   rt   rá   rv   )r   r#  Ú	respawnedÚspawnedÚfailedÚlog_pathÚoriginalr   Úlog_fÚprocÚexcÚ_Úerr_msgs   &            r   Ú_respawn_dashboard_processesrA  ¥  s  € õ 1Ø!#€IØCE€GØ57€FÙÓ  6Õ)Ð,CÕC€HÜ	×	Ò	œW×	%Õ	%Ø�‰×Ñ d°TÐÔ:÷ 
&ó ˆÜ:¸8ÓDˆð ˜'Ô! k¸Ô&@Ø-˜Ð- Ð-ˆGð	9Ü�h ×%Ô%¨Ü!×'Ò'Ø¤:×#5Ñ#5¸eÌJ×L]ÑL]Ø&*°dô<�÷ &ð �N‰N˜H¨tÐ4Ö5ñ ÷$ Ü�
Š
Ô2Ô3Û#*Ñˆ˜4Ø�9‰9‹;ÒØ×Ñ˜WÖ%à�M‰M˜8Ð0NÜ1PÐQTÐ0UÐU]Ð^b×^mÑ^mÐ]nÐnoð/qð rö sñ	 $+ó ˆÜÐ#¤E§J¢J¨wÓ$7Ð#8Ð9Ö:ñ ã%Ñˆ�GÜÐ+¬E¯JªJ°wÓ,?Ð+@ÀÀGÀ9ÐMÖNñ  &ñ ,2Ô2©6™˜ 1 aŠH©6Ò2Ð2÷I 
&×	%Ð	%ú÷ &×%Ð%ûô
 œÐ$ô 	9Ø�M‰M˜8¬c°#«hÐ7×8Ó8ûð	9üó* 3sB   ÁG*ÂHÂ#9G>ÃHÇIÇ*G;	Ç>HÈ		HÈIÈ#IÉIc                   óR   a € ] tR tRt o Rt]]]3tR t	R t
R tR tR tR tR	tV tR
# )Ú_UpdateOutputStreamiØ  z·stdout/stderr wrapper for ``hermes update``: mirrors to ``logs/update.log`` and, once the
terminal vanishes (BrokenPipe/OSError/ValueError), drops screen output instead of the update.c                ó,   € Wn         W n        R V n        R# )FN)Ú	_originalÚ_logÚ_original_broken)Úselfr;  Úlog_files   &&&r   Ú__init__Ú_UpdateOutputStream.__init__Þ  s   € Ø!ŒØŒ	Ø %ˆÖr   c                óº  € V P                   eG   \        P                  ! \        4      ;_uu_ 4        V P                   P	                  V4       R R R 4       V P
                  '       g    V P                  P	                  V4      # \        V\        \        34      '       d   \        V4      # ^ #   + '       g   i     Lg; i  T P                   d    RT n         LVi ; i©NT)rF  r,  r-  Ú	ExceptionÚwriterG  rE  Ú_BROKENrß   r   ÚbytesrŒ   )rH  ré   s   &&r   rO  Ú_UpdateOutputStream.writeã  sž   € à�9‰9Ò Ü×$Ò$¤Y×/Õ/Ø—	‘	—‘ Ô%÷ 0à×$×$Ð$ð-Ø—~‘~×+Ñ+¨DÓ1Ð1ô ' t¬c´5¨\×:Ò:Œs�4‹yÐAÀÐA÷ 0×/ûð
 —<‘<ô -Ø(,�Ö%ð-ús   ±B,Á(B? Â,B<	Â?CÃCc                ón  € V P                   eF   \        P                  ! \        4      ;_uu_ 4        V P                   P	                  4        R R R 4       V P
                  '       d   R #  V P                  P	                  4        R #   + '       g   i     LA; i  T P                   d    RT n         R # i ; irM  )rF  r,  r-  rN  ÚflushrG  rE  rP  ©rH  s   &r   rT  Ú_UpdateOutputStream.flushï  sy   € Ø�9‰9Ò Ü×$Ò$¤Y×/Õ/Ø—	‘	—‘Ô!÷ 0à× × Ð Ùð	)Ø�N‰N× Ñ Ö"÷ 0×/ûð �|‰|ô 	)Ø$(ˆD×!ð	)ús   ±BÁ)B ÂB	ÂB4Â3B4c                ó„   € V P                   '       d   R #  V P                  P                  4       #   \         d     R # i ; i©F)rG  rE  ÚisattyrN  rU  s   &r   rY  Ú_UpdateOutputStream.isattyú  s;   € Ø× × Ð Ùð	Ø—>‘>×(Ñ(Ó*Ð*øÜô 	Úð	ús   –0 °?¾?c                ó6   € V P                   P                  4       # ©N)rE  ÚfilenorU  s   &r   r]  Ú_UpdateOutputStream.fileno  s   € à�~‰~×$Ñ$Ó&Ð&r   c                ó.   € \        V P                  V4      # r\  )ÚgetattrrE  )rH  Únames   &&r   Ú__getattr__Ú_UpdateOutputStream.__getattr__  s   € Ü�t—~‘~ tÓ,Ð,r   )rF  rE  rG  N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚBrokenPipeErrorrŠ   r*   rP  rJ  rO  rT  rY  r]  rb  Ú__static_attributes__Ú__classdictcell__)Ú__classdict__s   @r   rC  rC  Ø  s=   ø‡ € ñeð  ¨Ð4€Gò&ò

Bò	)òò'÷-ð -r   rC  c                ó$   € V ^8„  d   QhR\         /# )r	   Úgateway_mode©rM   )r   s   "r   r   r   
  s   € ÷ %ñ %¬Tñ %r   c           	     ód  € R\         P                  R\         P                  RRRR/p^ RIpV '       gi   \	        VR4      '       dW   \
        P                  ! \        \        4      ;_uu_ 4        VP                  VP                  VP                  4       RRR4        ^ RIHp V! 4       R	,          pVP                  R
R
R7       \        VR,          R^RR7      p^ RIp\         P"                  P%                  R4      R8X  d   RMRpVP'                  RV RVP                  P)                  4       P+                  RR7       R24       WQR&   \-        VR,          V4      \         n        \-        VR,          V4      \         n        R
VR&   V#   + '       g   i     Lý; i  \.         d
    RTR&    T# i ; i)uX  Protect ``cmd_update`` from SIGHUP (â†’ SIG_IGN, inherited by pip/git children) and broken pipes
(stdio wrapped in ``_UpdateOutputStream``). SIGINT/SIGTERM are left alone â€” legitimate cancels.
Gateway updates are already detached, but still need the log mirror for the
Desktop progress watchdog. Returns state for ``_finalize_update_output``.Úprev_stdoutÚprev_stderrrI  NÚ	installedFÚSIGHUP©Úget_default_hermes_rootr$  Tr%  z
update.logrë   r@   )Ú	bufferingrD   ÚHERMES_UPDATE_POST_SWAPÚ1zcontinued on the pulled codeÚstartedz
=== hermes update rd   Úseconds)Útimespecz ===
)rm   rq   rw   ÚsignalÚhasattrr,  r-  r*   rŠ   rt  ÚSIG_IGNr+  rv  r/  rÜ   ÚdatetimerØ   Úenvironr¤   rO  ÚnowÚ	isoformatrC  rN  )rn  ÚstateÚ_signalÚ_get_root_homeÚlogs_dirrI  Ú_dtÚstages   &       r   Ú_install_hangup_protectionrŠ  
  si  € ð 	”s—z‘z =´#·*±*¸jÈ$ÐP[Ð]bðd€Eó çœG G¨X×6Ò6ä× Ò ¤¬W×5Õ5Ø�N‰N˜7Ÿ>™>¨7¯?©?Ô;÷ 6ð!õ 	OÙ!Ó# fÕ,ˆØ�‰˜t¨dˆÔ3Ü˜ <Õ/°ÀÈGÔTˆãä24·*±*·.±.ÐAZÓ2[Ð_bÔ2bÑ.ÐhqˆØ�‰Ð-¨e¨W°A°c·l±l×6FÑ6FÓ6H×6RÑ6RÐ\eÐ6RÓ6fÐ5gÐgmÐnÔoà$ˆjÑÜ(¨¨}Õ)=¸xÓHŒŒ
Ü(¨¨}Õ)=¸xÓHŒŒ
Ø!ˆˆkÑð €L÷3 6×5ûô, ô !Ø ˆˆjÒà€Lð!ús   Á,'FÂC*F ÆF	ÆF/Æ.F/c                óÐ  € V '       g   R# V P                  R4      '       d©   \        P                  ! \        4      ;_uu_ 4        V P                  R\        P
                  4      \        n        RRR4       \        P                  ! \        4      ;_uu_ 4        V P                  R\        P                  4      \        n        RRR4       V P                  R4      pVeN   \        P                  ! \        4      ;_uu_ 4        VP                  4        VP                  4        RRR4       R# R#   + '       g   i     LÈ; i  + '       g   i     L‡; i  + '       g   i     R# ; i)zWRestore stdio and close the update.log handle opened by ``_install_hangup_protection``.Nrs  rq  rr  rI  )	r¤   r,  r-  rN  rm   rq   rw   rT  Úclose)r„  rI  s   & r   Ú_finalize_update_outputr�  2  sÑ   € çÙØ‡y�y�×ÒÜ× Ò ¤×+Õ+ØŸ™ =´#·*±*Ó=ŒCŒJ÷ ,ä× Ò ¤×+Õ+ØŸ™ =´#·*±*Ó=ŒCŒJ÷ ,à�y‰y˜Ó$€HØÒÜ× Ò ¤×+Õ+Ø�N‰NÔØ�N‰NÔ÷ ,Ñ+ñ ÷ ,×+úç+×+ú÷ ,×+Ð+ús$   Á*D.Â*EÄ!EÄ.D>	ÅE	ÅE%	c                ó$   € V ^8„  d   QhR\         /# rÄ   r„   )r   s   "r   r   r   B  s   € ÷ !ñ !¤#ñ !r   c            	     óØ  € ^ RI Hp Hp ^ RIHp V ! 4       p. pV! 4        Fr  w  rV\        V4      pVf   K  Vw  r‰p
WS9   d   W5,          w  rºT;'       g    T	p	V
^ 8:  g    V! V4      '       d   \        Wš4      '       g   K_  VP                  WVV34       Kt  	  V'       g   \        R4       ^ # \        \        V4       R24       V F  w  rVp\        RV RV RV 24       K  	  \        V4      # )aê  Print live listening dashboard/serve processes and return the count.

Serve-mode backends are INCLUDED: ``--stop`` kills them, so hiding them from
``--status`` let an operator kill what they couldn't see.

Ledger-registered serves (profiled launches the argv scan can't match) surface via the spawn-ledger
augmentation in _scan_dashboard_processes, and the ledger's recorded bind replaces the argv port so
``--port 0`` backends are probed on the port the OS actually gave them. See #81564.
)Ú_ledger_serve_bindsr   )Ú_pid_existsz/No hermes dashboard or serve processes running.z, hermes dashboard/serve process(es) running:z    PID z [z]: )
r   r�  r   Úgateway.statusr‘  r1   Ú_dashboard_listeningru   rt   rŒ   )r�  r   r‘  ÚbindsÚliver   r   Úruntimer,   r.   r-   Úledger_hosts               r   Ú_report_dashboard_statusr˜  B  sè   € ÷ ZÝ*ÙÓ!€EØ')€DÙ1Ö3‰ˆÜ*¨7Ó3ˆØŠ?ÙØ"Ñˆ�DØŒ<Ø %¥
ÑˆKØ×&Ð& $ˆDØ�1Œ9™K¨×,Ò,Ô4HÈ×4TÒ4TÙØ�‰�S 4Ð(Ö)ñ 4÷ ÜÐ?Ô@Ùä	ŒS�‹YˆKÐCÐ
DÔEÛ"Ñˆ�dÜ�˜˜˜R ˜v S¨¨	Ð2Ö3ñ #äˆt‹9Ðr   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r	   r.   r-   r
   rž   )r   s   "r   r   r   f  s!   € ÷ ñ œsð ¬#ð ´$ñ r   c                ó¼   € ^ RI p VP                  \        V 4      V3RR7      ;_uu_ 4         RRR4       R#   + '       g   i     R# ; i  \         d     R# i ; i)z_True when something accepts TCP connections at host:port (even a 401 proves a dashboard is up).Ng      ø?rU   TF)ÚsocketÚcreate_connectionr9   rŠ   )r.   r-   r›  s   && r   r“  r“  f  sP   € ãðØ×%Ñ%Ô'<¸TÓ'BÀDÐ&IÐSVÐ%×WÕWØ÷ X×W×WÒWûäô Úðús+   †&A ¬8®A ¸A		ÁA Á	A ÁAÁAc                ó0   € V ^8„  d   QhR\         R\        /# )r	   Úmessager
   )r   r   )r   s   "r   r   r   p  s   € ÷ ñ ”Sð ¬hñ r   c                 óH   € \        V 4       \        P                  ! ^4       R# )rZ   N)rt   rm   Úexit)rž  s   &r   Ú_cancelr¡  p  s   € Ü	ˆ'„NÜ‡H‚HˆQ†Kr   c                ó   € V ^8„  d   QhRR/# )r	   r
   Nrf   )r   s   "r   r   r   u  s   € ÷ pDñ pD°tñ pDr   c                ó@  € \        V RR4      ;'       g    Rp ^ RIHp V! V4      '       g   R#   ^ RIHp T! 4       '       d   R#  \        P                  P                  4       '       d%   \        P                  P                  4       '       g   R# \        RT R24       \        R4       \        4        \        R	4       \        R
4       \        R4        \        R4      P                  4       ;'       g    RpXR8X  d,   \        4        \        R4       \        P                   ! ^ 4       TR8w  d   \        4        ^ RIp^ RIp\        4         \'        R4      P                  4       ;'       g    RpTP#                  R4      pTP#                  R4      p	X'       g   \        R4       TX	8w  d   \        R4        ^ RIHp
 X
! T4      pTP-                  ^ 4      p ^ RIHpHp ^ RIHp T! 4       pTP9                  R/ 4      P9                  R/ 4      pXTR&   TTR&   RTR &   \;        TP=                  R!R4      ;'       g    R4      P                  4       '       g   TTR!&   T! T4      '       d   \        R"4       T! T4        ^ R$IH p T! R%R&7       \        4        \        R)X R24       \        R*4       \        R+4       R#   \         d     R# i ; i  \         d     R# i ; i  \        \        3 d    \        R4        EL
i ; i  \        \        3 d    \        R4        EL’i ; i  \         d   p\        RT 24        Rp?EL‰Rp?ii ; i  \         d   p\        R#T 24        Rp?LðRp?ii ; i  \         d   p\        R'T R(24        Rp?ELRp?ii ; i),a^  Offer to configure dashboard auth when the gate engages and no provider exists.

``start_server`` fails closed for a non-loopback bind / ``dashboard.public_url``
without a ``DashboardAuthProvider``; prompt an interactive operator first.
No-op (fail-closed backstop stays) when the gate doesn't engage, a provider
exists, or stdin/stdout isn't a TTY.
r.   r#   )Úshould_require_dashboard_authN)Úlist_providersuB   
âš  Dashboard authentication is required for this configuration (z).z‚  Non-loopback binds and configured external dashboard.public_url values require authentication (--insecure does not bypass this).z0  How do you want to authenticate the dashboard?z?    [1] Username & password (quickest; for a trusted LAN / VPN)zO    [2] OAuth via Nous Portal (run `hermes dashboard register`)
    [3] Cancel
z  Choice [1]: ry  z
  Cancelled.Ú2aR    Run this on the host where the dashboard lives, then start the dashboard again:
    hermes dashboard register
  It provisions a Nous Portal OAuth client and writes HERMES_DASHBOARD_OAUTH_CLIENT_ID into ~/.hermes/.env for you.
  Docs: https://hermes-agent.nousresearch.com/docs/user-guide/features/web-dashboard#authentication-gated-modez  Username [admin]: Úadminz  Password: z  Confirm password: u"     âœ— Empty password â€” aborting.u)     âœ— Passwords don't match â€” aborting.)Úhash_passwordu,     âœ— Could not load the password provider: )Úload_configÚsave_config)Ú*ensure_basic_auth_plugin_enabled_in_configr$   Ú
basic_authÚusernameÚpassword_hashr5   ÚpasswordÚsecretuJ     âœ“ Re-enabled the bundled 'basic' auth plugin (was in plugins.disabled)u#     âœ— Failed to write config.yaml: )Údiscover_pluginsT)Úforceu"     âš  Plugin re-discovery failed (zS); the gate may still fail closed. Set the password again or restart the dashboard.u/     âœ“ Username/password auth configured (user: z4    Saved to config.yaml under dashboard.basic_auth.z5    Sign in at the dashboard with these credentials.
)!r`  Úhermes_cli.web_serverr¤  rN  Úhermes_cli.dashboard_authr¥  rm   r(  rY  rq   rt   Úinputr+   ÚEOFErrorÚKeyboardInterruptr¡  r   ÚgetpassÚsecretsr   Úplugins.dashboard_auth.basicr¨  Útoken_urlsafeÚhermes_cli.configr©  rª  Úhermes_cli.plugins_cmdr«  Ú
setdefaultr   r¤   Úhermes_cli.pluginsr±  )rQ   r.   r¤  r¥  Úchoicer¸  r¹  r­  r¯  Úconfirmr¨  r>  r®  r°  r©  rª  r«  ÚcfgÚbasicr±  s   &                   r   Ú)_maybe_setup_dashboard_auth_interactivelyrÄ  u  s[  € ô �4˜ Ó-×<Ð<°€DðÝGÙ,¨T×2Ò2Ùð 3ð
Ý<Ù×ÒÙð ô
 �I‰I×Ñ×Ò¤3§:¡:×#4Ñ#4×#6Ò#6Ùä	ÐOÐPTÈvÐUWÐ
XÔYÜ	ð	Kôô 
„GÜ	Ð
<Ô=Ü	Ð
KÔLÜ	Ð
]Ô^ð"ÜÐ'Ó(×.Ñ.Ó0×7Ð7°Cˆð �„}ÜŒÜðJô	
ô 	�Š�Œà�„}ÜŒ	ãÛÜ	„Gð"ÜÐ4Ó5×;Ñ;Ó=×HÐHÀˆØ—?‘? >Ó2ˆØ—/‘/Ð"8Ó9ˆ÷ ÜÐ4Ô5Ø�7ÔÜÐ;Ô<ðFÝ>ñ " (Ó+€Mà×"Ñ" 2Ó&€Fð=ß>ÝUÙ‹mˆØ—‘˜{¨BÓ/×:Ñ:¸<ÈÓLˆØ$ˆˆjÑØ!.ˆˆoÑØˆˆjÑÜ�5—9‘9˜X rÓ*×0Ð0¨bÓ1×7Ñ7×9Ò9Ø$ˆE�(‰Oñ 6°c×:Ò:ÜÐ^Ô_Ù�CÔð
OÝ7Ù˜tÕ$ô
 
„GÜ	Ð;¸H¸:ÀRÐ
HÔIÜ	Ð
@ÔAÜ	Ð
BÖCøôE ô Úðûô ô Úðûô$ Ô'Ð(ô "ÜÐ ×!ð"ûô4 Ô'Ð(ô "ÜÐ ×!ð"ûô ô FÜÐ>¸s¸eÐD×EÒEûðFûô. ô =ÜÐ5°c°UÐ;×<Ñ<ûð=ûô ô OÜÐ2°3°%ð 8Nð N÷ 	Oò 	OûðOús§   ™K ±K Ã#K% ÅL Å0%L Æ;L+ ÇA#M È?M ÉM É-M ÊM8 ËKËKËK"Ë!K"Ë%LÌLÌL(Ì'L(Ì+MÌ6M
Í
MÍM5ÍM0Í0M5Í8NÎNÎNc                ó0   € V ^8„  d   QhR\         R\         /# ©r	   r
  r
   r3   )r   s   "r   r   r   è  s   € ÷ Qñ Q¤sð Q¬sñ Qr   c           	     óÊ
  aa€ \         P                  R8X  d   ^ RIHp V! V 4      # ^ RIo\
        P                  P                  V 4      '       g   \        R4      h\        P                  ! 4       R,          R,          p \        V 4      P                  V4      p\        TP                  4      ^8w  g/   \        P                   ! RTP                  ^ ,          4      '       g   \        R	4      h\        P                   ! R
TP                  ^,          4      '       g   \        R4      h\
        P"                  \%        \
        R^ 4      ,          \%        \
        R^ 4      ,          p\
        P"                  \%        \
        R^ 4      ,          p\'        \
        R4      '       d   \
        P(                  ! 4       MRoR TT3R llpR!pR!p	R!p
  \
        P*                  ! Y%4      pT! TR4       \
        P*                  ! TP                  ^ ,          YXR7      p	T! T	R4       \
        P*                  ! TP                  ^,          YiR7      p
\
        P2                  ! T
4      pSP5                  TP6                  4      '       g   \        R4      hTP8                  ^@8w  d   \        R4      hSe   TP:                  S8w  d   \        R4      hSe,   TP6                  R,          R",          '       d   \        R4      h\
        P<                  ! T
RRR7      ;_uu_ 4       pR!p
TP?                  ^A4      pRRR4       \        P                   ! R X4      '       g   \        R4      hTT
^ 8¼  d   \
        P@                  ! T
4       T	^ 8¼  dk   \B        PD                  ! \,        4      ;_uu_ 4        \
        PF                  ! TP                  ^,          T	R7       RRR4       \
        P@                  ! T	4       T^ 8¼  d   \
        P@                  ! T4       # #   \         d   p\        R4      ThRp?ii ; i  \         d    h \,         dC   pTP.                  \%        \1        R4      RR!4      8X  d   \        R4      Th\        R4      ThRp?ii ; i  + '       g   i     ELa; i  + '       g   i     LÓ; i  T
^ 8¼  d   \
        P@                  ! T
4       T	^ 8¼  d   \B        PD                  ! \,        4      ;_uu_ 4        \
        PF                  ! TP                  ^,          T	R7       RRR4       M  + '       g   i     M; i\
        P@                  ! T	4       T^ 8¼  d   \
        P@                  ! T4       i i ; i)#zGRead and unlink a Desktop SSH token from its private runtime directory.rO   )Ú
read_tokenNz)--ssh-session-token-file must be absolutez.hermeszdesktop-sshz@--ssh-session-token-file must be under the desktop-ssh directoryz[0-9a-f]{32}z4--ssh-session-token-file has an invalid runtime pathz[0-9a-f]{16}\.tokenz0--ssh-session-token-file has an invalid filenameÚO_DIRECTORYÚ
O_NOFOLLOWrÙ   c                ó4   € V ^8„  d   QhR\         R\        RR/# )r	   ÚfdÚwhatr
   Nr“   )r   s   "r   r   Ú2_read_ssh_session_token_file.<locals>.__annotate__  s&   € ÷ Wñ W”sð W¤#ð W¨$ñ Wr   c                 ó2  <€ \         P                  ! V 4      pSP                  VP                  4      '       g   \	        R V 24      hSe!   VP
                  S8w  d   \	        RV R24      hVR8X  d&   VP                  R,          R8w  d   \	        R4      hR# R# )z'--ssh-session-token-file has an unsafe Nz--ssh-session-token-file z has the wrong ownerúparent directoryéÿ  iÀ  z6--ssh-session-token-file parent has unsafe permissions)rØ   ÚfstatÚS_ISDIRÚst_modeÚ
SystemExitÚst_uid)rÌ  rÍ  ÚstÚ_statrâ   s   && €€r   Ú
_check_dirÚ0_read_ssh_session_token_file.<locals>._check_dir  sŠ   ø€ Ü�XŠX�b‹\ˆØ�}‰}˜RŸZ™Z×(Ò(ÜÐFÀtÀfÐMÓNÐNØŠ?˜rŸy™y¨CÔ/ÜÐ8¸¸Ð>RÐSÓTÐTØÐ%Ô%¨2¯:©:¸Õ+=À%Ô*GÜÐUÓVÐVñ +HÑ%r   zruntime root)Údir_fdrÐ  ÚerrnoÚELOOPz%--ssh-session-token-file is a symlinkz*--ssh-session-token-file is not accessiblez.--ssh-session-token-file is not a regular filez2--ssh-session-token-file contains an invalid tokenz,--ssh-session-token-file has the wrong ownerrÑ  z/--ssh-session-token-file has unsafe permissionsÚrr‡   )rD   z[0-9a-f]{64}r–   iþÿÿ)$rm   rn   Úhermes_cli.windows_ssh_runtimerÈ  ÚstatrØ   r
  ÚisabsrÕ  r   rÊ   Úrelative_tor*   rŒ   r�   r'   Ú	fullmatchÚO_RDONLYr`  r~  rÙ   rÜ   rŠ   rÜ  Ú
__import__rÒ  ÚS_ISREGrÔ  Úst_sizerÖ  Úfdopenr  rŒ  r,  r-  Úunlink)r
  rÈ  Ú
token_rootÚrelativer>  Údirectory_flagsÚ
file_flagsrÙ  Úroot_fdÚdirectory_fdÚfile_fdÚ	file_statÚtoken_streamÚtokenrØ  râ   s   &             @@r   Ú_read_ssh_session_token_filerô  è  s÷  ù€ ä
‡|�|�wÔÝ=Ù˜$ÓÐãä�7‰7�=‰=˜×ÒÜÐDÓEÐEô —’“˜yÕ(¨=Õ8€JðfÜ˜“:×)Ñ)¨*Ó5ˆô ˆ8�>‰>Ó˜aÔ¤r§|¢|°OÀXÇ^Á^ÐTUÕEV×'WÒ'WÜÐOÓPÐPÜ�<Š<Ð.°·±¸qÕ0A×BÒBÜÐKÓLÐLä—k‘k¤G¬B°¸qÓ$AÕAÄGÌBÐP\Ð^_ÓD`Õ`€OÜ—‘œw¤r¨<¸Ó;Õ;€JÜ ¤ X×.Ò.Œ"�)Š)Œ+°D€C÷Wñ Wð €GØ€LØ€Gð'ð	TÜ—g’g˜jÓ:ˆGÙ�w Ô/ÜŸ7š7 8§>¡>°!Õ#4°oÔVˆLÙ�|Ð%7Ô8Ü—g’g˜hŸn™n¨QÕ/°ÔQˆGô —H’H˜WÓ%ˆ	Ø�}‰}˜Y×.Ñ.×/Ò/ÜÐMÓNÐNØ×Ñ Ô"ÜÐQÓRÐRØŠ?˜y×/Ñ/°3Ô6ÜÐKÓLÐLØŠ? 	× 1Ñ 1°EÕ 9¸V×CÔCÜÐNÓOÐOä�YŠY�w ¨k×:Õ:¸lØˆGØ ×%Ñ% bÓ)ˆE÷ ;ô �|Š|˜O¨U×3Ò3ÜÐQÓRÐRØà�aŒ<Ü�HŠH�WÔØ˜1ÔÜ×$Ò$¤W×-Õ-Ü—	’	˜(Ÿ.™.¨Õ+°LÕA÷ .ä�HŠH�\Ô"Ø�aŒ<Ü�HŠH�WÕð øô{ ô fÜÐ[Ó\ÐbeÐeûðfûô< ô 	ØÜô 	TØ�y‰yœG¤J¨wÓ$7¸À"ÓEÔEÜ Ð!HÓIÈsÐRÜÐIÓJÐPSÐSûð	Tú÷ ;×:Ð:ú÷ .×-ûð �aŒ<Ü�HŠH�WÔØ˜1ÔÜ×$Ò$¤W×-Õ-Ü—	’	˜(Ÿ.™.¨Õ+°LÕA÷ .×-×-Ð-úä�HŠH�\Ô"Ø�aŒ<Ü�HŠH�WÕð ús“   Á>O? ÇA:P È?6R  É6BR  ÌQ9Ì!$R  ÍR  Î*RÏ?PÐ
PÐPÐQ6Ð3Q6Ð4=Q1Ñ1Q6Ñ6R  Ñ9R
	Ò	R  ÒRÒ AU"Ó'*T	Ô	U"ÔT*Ô%=U"c                ó0   € V ^8„  d   QhR\         R\        /# rÆ  rL   )r   s   "r   r   r   <  s   € ÷ 1ñ 1¬ð 1´ñ 1r   c                ó@   € V '       g   R# RV P                  RR4      9   # )zõTrue when *path* is an Electron-packaged renderer dist (``app.asar[.unpacked]/dist``).

A standalone ``hermes dashboard`` inheriting that ``HERMES_WEB_DIST`` would
serve the desktop frontend in the browser ("Desktop IPC bridge is unavailable").
Fzapp.asarÚ\r•   )rA   )r
  s   &r   Ú_is_electron_packaged_web_distrø  <  s    € ÷ ÙØ˜Ÿ™ d¨CÓ0Ñ0Ð0r   c                 óÐ   €  ^ RI Hp  V P                  V P                  4      pVe   VP                  '       g   R# V P                  V4      '       d   V# R#   \         d     R# i ; i)a  Live host serve/dashboard record to attach to, or ``None``.

Record-based discovery replaces the old bare-TCP probe: "something accepts a connection on
this port" proved nothing about WHO answers (a foreign service, or a recycled PID's new
owner). The record carries ``(pid, createTime)`` so liveness is proved against the same
incarnation, and its token fingerprint must still match the 0600 token file the owner wrote.
The record only nominates a CANDIDATE; :func:`_attach_to_host_backend` makes it prove itself.
©Úhost_rendezvousN)Úgatewayrû  Úread_recordÚ
ROLE_SERVEr-   Úrecord_token_is_consistentrN  )ÚhrÚrecords     r   Ú_host_backend_attachmentr  G  sY   € ðÝ1à—‘ §¡Ó.ˆØŠ> §§ ÙØ×6Ñ6°v×>Ò>ˆvÐHÀDÐHøÜô Úðús"   ‚6A »A ÁA ÁA ÁA%Á$A%c                ó$   € V ^8„  d   QhR\         /# rÄ   )r   )r   s   "r   r   r   [  s   € ÷ ñ ¬3ñ r   c                óè   € \        4       pV f   \        P                  R,          MT  FF  p\        V4      P	                  R^4      ^ ,          pVR9   g   K.  VP                  VR,          4       KH  	  V# )ay  Which of ``--host``/``--port`` the operator actually typed.

argparse defaults are indistinguishable from a typed value in ``args``, and the difference is
load-bearing: an unset ``--port`` may attach to whatever port the host owner bound, but a
typed ``--port 8899`` or ``--host 0.0.0.0`` (LAN access) must never be silently answered with
a loopback attach on some other port.
:rZ   NNÚ=r  )ú--hostú--port)r   rm   rì   r   r[   Úadd)rì   Útypedró  ra  s   &   r   Ú_explicit_endpoint_flagsr
  [  sa   € ô ‹E€EØ"&¢,”#—(‘(˜2–,°DÒ8ˆÜ�5‹z×Ñ  QÓ'¨Õ*ˆØÐ'Ö'Ø�I‰I�d˜2•hÖñ 9ð €Lr   c                ó0   € V ^8„  d   QhR\         R\        /# )r	   r	  r
   )r   r   )r   s   "r   r   r   k  s   € ÷ ñ ¬Cð ´Cñ r   c                ó’  € RV9   dN   \        V RR4      p\        V\        4      '       d+   V^ 8”  d$   W1P                  8w  d   RV RVP                   R2# RV9   dl   \	        \        V RR4      ;'       g    R4      pVP
                  ;'       g    Rp0 Rmp0 RmpWE8H  ;'       g    WW9   ;'       d    WF9   pV'       g
   R	V R
V R2# R# )zUWhy an explicitly requested endpoint cannot be served by ``record`` ('' when it can).r-   Nz--port z (the host owner is on port ra   r.   r5   r#   z--host z (the host owner is bound to >   Ú	localhostú::1r#   >   Ú*r6   r7   )r`  rß   r   r-   r   r.   )	rQ   r  r	  Úwanted_portÚwanted_hostÚ
owner_hostÚloopbackÚwildcardÚ	reachables	   &&&      r   Ú_endpoint_conflictr  k  sÆ   € à�„Ü˜d F¨DÓ1ˆä�k¤3×'Ò'¨K¸!¬OÀÏ{É{Ô@ZØ˜[˜MÐ)EÀfÇkÁkÀ]ÐRSÐTÐTØ�„Üœ' $¨°Ó3×9Ð9°rÓ:ˆØ—[‘[×/Ð/ Kˆ
Ú4ˆÚ)ˆàÑ-×eÐe°*Ñ2H×2dÐ2dÈ[ÑMdˆ	ßØ˜[˜MÐ)FÀzÀlÐRSÐTÐTÙr   c                ó(   € V ^8„  d   QhR\         RR/# )r	   Úheadless_backendr
   Nro  )r   s   "r   r   r   ~  s   € ÷ Dñ D´Dð D¸Tñ Dr   c           	     ó®  € \        V RR4      '       g   \        4       '       d   R# \        4       pVf   R# ^ RIHp ^ RIHp VP                  V4      pVf   R# \        4       p\        WV4      pV'       dO   \        RVP                  V4       R24       \        RV R24       \        R	4       \        P                  ! V4       V'       gW   VP                  R
4      '       g@   \        RVP                  V4       R24       \        R4       \        P                  ! V4        ^ RIHp V! 4       p	\        V RR4      ;'       g    T	p
^ RIHp RV! VP)                  V4      4       RVP*                   RV
 2pV'       d   RMRp\        RV RVP,                   RVP*                   R24       \        RV
 RV 24       V'       gS   V P.                  '       gA   \0        P2                  ! \"        4      ;_uu_ 4        ^ RIpVP7                  V4       RRR4       \        P                  ! ^ 4       R#   \"         d    Rp	 ELi ; i  + '       g   i     L<; i)uE  Multiplex-only: a second `hermes serve`/`dashboard` attaches to the host backend.

Exactly ONE backend runs per host and multiplexes every profile, so a second invocation â€”
for ANY profile, the default included â€” reports the live one and exits 0 instead of binding
a second port. ``--isolated`` opts out (Desktop's SSH backend proves ownership with it) and
Desktop pool backends (HERMES_DESKTOP=1) keep their own lifecycle.

Exit 0 means "the host backend answered and serves what you asked for", and nothing else:

* the owner must ANSWER on its recorded port and identify itself (a record alone cannot see a
  graceful-shutdown window or a foreign listener that inherited the port) â€” a supervisor or
  `hermes update` relaunch landing in that window would otherwise exit 0 with NOTHING
  listening, reporting success for a dead service;
* an explicitly typed ``--port``/``--host`` the owner cannot serve is a REFUSAL naming the
  owner, never a silent redirect. It exits 78 (EX_CONFIG), the deliberate-refusal code
  ``RestartPreventExitStatus=78`` parks on: exit 1 under ``Restart=always`` was an infinite
  restart loop with nothing listening on the ingress port (#119824);
* a `hermes dashboard` user is never handed a headless backend's URL (no SPA behind it).

Returns normally â€” leaving the caller to BIND â€” when no owner answers.
ÚisolatedFNrú  )ÚGATEWAY_FATAL_CONFIG_EXIT_CODEz2Refusing to start: this host is already served by Ú.z  You asked for z=  Stop that backend, or drop the flag to use the running one.Ú	servesSpazB, which is a headless `hermes serve` backend with no dashboard UI.zO  Stop it and run `hermes dashboard`, or use --isolated for a dedicated server.©Úget_active_profile_nameÚdefaultÚopen_profiler5   )Úformat_url_hostzhttp://Ú:z
/?profile=Úbackendr$   zHermes z# already running on this host: PID z, port z  Managing profile 'z': )r`  Ú_is_desktop_owned_backendr  rü  rû  Úgateway.restartr  Úprobe_ownerr
  r  rt   Údescriberm   r   r¤   Úhermes_cli.profilesr  rN  Úhermes_cli.url_utilsr"  Ú	dial_hostr-   r   Úno_openr,  r-  Ú
webbrowserrÜ   )rQ   r  r  r   r  Úidentityr	  Úconflictr  ÚprofileÚwantedr"  Úurlrä   r-  s   &&             r   Ú_attach_to_host_backendr3  ~  sõ  € ô, ˆt�Z ×'Ò'Ô+D×+FÒ+FÙÜ%Ó'€FØ‚~Ùå-Ý>à�~‰~˜fÓ%€HØÒñ 	ä$Ó&€EÜ! $°Ó6€HßÜÐBÀ2Ç;Á;ÈvÓCVÐBWÐWXÐYÔZÜÐ   
¨!Ð,Ô-ÜÐMÔNÜ�ŠÐ/Ô0ç H§L¡L°×$=Ò$=ÜÐBÀ2Ç;Á;ÈvÓCVÐBWð XQð Qô 	RäÐ_Ô`Ü�ŠÐ/Ô0ðÝ?Ù)Ó+ˆô �T˜>¨2Ó.×9Ð9°'€FÝ4à‘O B§L¡L°Ó$8Ó9Ð:¸!¸F¿K¹K¸=È
ÐSYÐRZÐ
[€Cç(‰9¨k€DÜ	ˆG�D�6Ð<¸V¿Z¹Z¸LÈÐPV×P[ÑP[È}Ð\]Ð
^Ô_Ü	Ð   ¨¨C¨5Ð
1Ô2ß D§L§L LÜ× Ò ¤×+Õ+ÛØ�O‰O˜CÔ ÷ ,ô ‡H‚HˆQ†Køô ô Ø‹ðú÷ ,×+ús   Ä$H0 Ç:IÈ0IÉ IÉI	c                ó@   € V ^8„  d   QhR\         R\        R\        RR/# )r	   Ú_headless_backendÚ_ssh_owner_nonceÚ_token_filer
   N)rM   r   )r   s   "r   r   r   Å  s2   € ÷ B5ñ B5Ü!ðB5Ü58ðB5ÜGJðB5ØOSñB5r   c                ó¬  €  ^ RI Hp V! 4       pVR9   g7   \        V RR4      '       g$   \        V RR4      '       g   \	        4       '       d   R# \        RV R	24       \        P                  R
RRRV'       d   RMRR\        V P                  4      RV P                  RV.pVRV.3VRV.3V P                  R.3\        V RR4      R.3\        V RR4      R.33 F   w  rxV'       g   K  VP                  V4       K"  	  ^ RIHp	 V	! RRR7      p
 ^ RIHp \        V! 4       4      V
R&   \        P$                  R8X  d>   \&        P(                  ! WjR7      p\        P*                  ! VP-                  4       4       R# \.        P0                  ! \        P                  Wj4       R#   \         d    Rp EL i ; i  \         d    T
P#                  RR4        L¬i ; i) a  Route a named-profile launch to the single MACHINE dashboard (per-request ``?profile=`` scoping
makes one server per profile pure fragmentation).

No-record fallback to :func:`_attach_to_host_backend`, which already attached (and exited)
when the host publishes a live rendezvous record: re-exec pinned to ``-p default`` (so
``_apply_profile_override`` can't re-route via the sticky active_profile file). ``--isolated``
opts out; Desktop pool backends (HERMES_DESKTOP=1) stay per-profile. Returns normally when no
routing applies.
r  r   r  Fr!  r5   Nz+Routing to the machine dashboard (profile 'zB' preselected). Use --isolated for a dedicated per-profile server.z-mzhermes_cli.mainr	  r%   r$   r  r  z--open-profilez--ssh-owner-noncez--ssh-session-token-filerù   Úinsecurez
--insecureÚ
skip_buildz--skip-build)Úbuild_subprocess_env)Úscrub_secretsÚinherit_profile_homeru  ÚHERMES_HOMErO   )Úenv)r   Úcustom)r)  r  rN  r`  r%  rt   rm   Ú
executabler   r-   r.   r,  ÚextendÚtools.environments.localr;  r+  rv  Úpoprn   r=   r0  r   ÚwaitrØ   Úexecvpe)rQ   r5  r6  r7  r  Ú_launch_profileÚreexec_argvri   Úextrar;  r?  rv  r=  s   &&&&         r   Ú_route_named_profile_dashboardrJ  Å  sÁ  € ð$Ý?Ù1Ó3ˆð
 	Ð0Ô0Ü�4˜ U×+Ò+Ü�4˜¨×,Ò,Ü$×&Ò&áä	Ø
5°oÐ5Fð GKð 	Lôô
 	�‰˜Ð/Øˆi÷ %‰¨+Ø”#�d—i‘i“.Ø�$—)‘)Ø˜/ð+€Kð 
Ð/Ð1AÐBÐCØ	Ð1°;Ð?Ð@Ø	�‰˜�}Ð%Ü	��z 5Ó	)¨L¨>Ð:Ü	��| UÓ	+¨nÐ-=Ð>ó@‰ˆ÷ ‰7Ø×Ñ˜uÖ%ñ@õ >ñ ¨UÈÔ
O€Cð%Ý<Ü Ñ!8Ó!:Ó;ˆˆMÑô
 ‡|�|�wÔÜ×Ò Ô5ˆÜ�Š�—‘“Öä
�
Š
”3—>‘> ;Ö4øôi ô $Ø#‹ð$ûôX ô %Ø�‰�˜tÖ$ð%ús#   ‚F ÄF3 ÆF0Æ/F0Æ3GÇGc                ó(   € V ^8„  d   QhR\         RR/# )r	   r5  r
   Nro  )r   s   "r   r   r   
  s   € ÷ =Hñ =H¼ð =HÀ$ñ =Hr   c                óæ  € ^ RI Hp ^ RIHp \	        V RR4      pV'       d   R\
        P                  R&   R# R\
        P                  9  d:   V'       g2   V! VR,          R	R
7      '       g   \        P                  ! ^4       R# R# V'       Ed1   R\
        P                  9   d!   \        \
        P                  R,          4      MVR,          R,          pVR,          P                  4       '       g¿   R\
        P                  9  pV'       d+   \        RV 24       \        R4       V! VR,          R	R
7       VR,          P                  4       '       gR   \        RV 24       V'       d   \        R4       \        \        4       \        R4       \        P                  ! ^4       \        R4       \        RV 24       R# \        \
        P                  R,          4      P                  4       pVR,          P                  4       '       g?   \        RV 24       \        \        4       \        R4       \        P                  ! ^4       \        V4      \
        P                  R&   \        RV 24       R# )uo  Build or validate the web UI dist before the server imports.

``serve`` sets HERMES_SERVE_HEADLESS so mount_spa() stays off. Otherwise build
unless HERMES_WEB_DIST / --skip-build promise a dist â€” then verify index.html
(else the server serves 404s). --skip-build on the default location gets ONE
recovery build; a caller-managed HERMES_WEB_DIST can't be populated.
)ÚPROJECT_ROOT)Ú_build_web_uir:  Fry  ÚHERMES_SERVE_HEADLESSÚHERMES_WEB_DISTÚwebT)ÚfatalÚ
hermes_cliÚweb_distz
index.htmlu6   âš  --skip-build was passed but no web dist found at: z0  Attempting one recovery build of the web UI...u6   âœ— --skip-build was passed but no web dist found at: z3  The recovery build did not produce a usable dist.z.  Or drop --skip-build to build automatically.u(     âœ“ Recovery build produced a web distu8   â†’ Skipping web UI build (--skip-build); using dist at u5   âœ— HERMES_WEB_DIST is set but no web dist found at: zD  Or unset HERMES_WEB_DIST to build and use the default web UI dist.u)   â†’ Using web dist from HERMES_WEB_DIST: N)Úhermes_cli.mainrM  Úhermes_cli.main_web_buildrN  r`  rØ   r�  rm   r   r   r  rt   Ú_PRE_BUILD_HINTÚ
expanduserr   )rQ   r5  rM  rN  r:  Ú
_dist_rootÚ_recoverables   &&     r   Ú_resolve_dashboard_web_distr[  
  sÍ  € õ -Ý7Ü˜˜|¨UÓ3€JßØ.1Œ�
‰
Ð*Ó+Ø	¤"§*¡*Ô	,·ZÙ˜\¨EÕ1¸×>Ó>Ü�HŠH�QŽKñ ?ç	ˆð
 !¤B§J¡JÔ.ô ”—‘Ð-Õ.Ô/à Õ,¨zÕ9ð 	ð ˜\Õ)×1Ñ1×3Ò3ð -´B·J±JÑ>ˆLßÜÐNÈzÈlÐ[Ô\ÜÐHÔIÙ˜l¨UÕ2¸$Õ?Ø Õ-×5Ñ5×7Ò7ÜÐNÈzÈlÐ[Ô\ßÜÐOÔPÜ”oÔ&ÜÐFÔGÜ—’˜”ÜÐ<Ô=ÜÐHÈÈÐUÖVô œ"Ÿ*™*Ð%6Õ7Ó8×CÑCÓEˆ
Ø˜\Õ)×1Ñ1×3Ò3ÜÐIÈ*ÈÐVÔWÜ”/Ô"ÜÐXÔYÜ�HŠH�QŒKô ),¨J«Œ�
‰
Ð$Ñ%ÜÐ9¸*¸ÐFÖGr   r\  )rf   rX  )z  Cancelled.)<rh  r,  rØ   r'   rá   r=   rm   r3  Úpathlibr   Útypingr   Úhermes_cli.cli_outputr   Úhermes_cli.process_identityr   r%  rW  r   r1   r9   Ú_DASHBOARD_SYSTEMD_UNITÚFileNotFoundErrorr  rŠ   ro   rH   r‚   r�   rœ   r™   r£   r­   r°   rµ   r¾   rÂ   rË   rñ   rü   r  r  r5  r   rA  rC  rŠ  r�  r˜  r“  r¡  rÄ  rô  rø  r  r
  r  r3  rJ  r[  rf   r   r   Ú<module>rb     sC  ðñó Û 	Û 	Û Û Û 
Û å Ý Ý ,Ý ]à[€ðPÀ$ð PØ8<÷Põ.õ8ð 5Ð à&¨
×(AÑ(AÀ7ÐKÐ õoð AX÷ Lõ^õõ$õõ8õ
Mõaõ3÷
õ,÷1÷hð,Ð[_÷ õð6 #&Ð õõ"03÷f/-ñ /-÷d%òPõ !õH÷õ
pDõfQõh1ò÷(õ õ&DõNB5÷J=Hr   